@1ly/mcp-server 0.1.3 → 0.1.4
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 +1 -1
- package/dist/budget.d.ts.map +1 -1
- package/dist/budget.js +19 -1
- package/dist/budget.js.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +78 -15
- package/dist/config.js.map +1 -1
- package/dist/http.d.ts +2 -0
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +27 -1
- package/dist/http.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/rate-limit.d.ts +24 -0
- package/dist/rate-limit.d.ts.map +1 -0
- package/dist/rate-limit.js +50 -0
- package/dist/rate-limit.js.map +1 -0
- package/dist/security-log.d.ts +55 -0
- package/dist/security-log.d.ts.map +1 -0
- package/dist/security-log.js +52 -0
- package/dist/security-log.js.map +1 -0
- package/dist/tools/update-avatar.d.ts.map +1 -1
- package/dist/tools/update-avatar.js +30 -4
- package/dist/tools/update-avatar.js.map +1 -1
- package/dist/wallet/evm.d.ts.map +1 -1
- package/dist/wallet/evm.js +35 -0
- package/dist/wallet/evm.js.map +1 -1
- package/dist/wallet/solana.d.ts.map +1 -1
- package/dist/wallet/solana.js +32 -0
- package/dist/wallet/solana.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -684,7 +684,7 @@ Update store avatar using a public URL or base64 image.
|
|
|
684
684
|
| Parameter | Type | Required | Description |
|
|
685
685
|
|-----------|------|----------|-------------|
|
|
686
686
|
| `avatarUrl` | string | No | Public image URL |
|
|
687
|
-
| `imageBase64` | string | No | Base64-encoded image
|
|
687
|
+
| `imageBase64` | string | No | Base64-encoded image (max 5MB decoded) |
|
|
688
688
|
| `mimeType` | string | No | `image/png`, `image/jpeg`, `image/webp`, `image/gif` |
|
|
689
689
|
| `filename` | string | No | Optional filename |
|
|
690
690
|
|
package/dist/budget.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"budget.d.ts","sourceRoot":"","sources":["../src/budget.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"budget.d.ts","sourceRoot":"","sources":["../src/budget.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAuD1C;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAuC/E"}
|
package/dist/budget.js
CHANGED
|
@@ -7,6 +7,7 @@ exports.checkAndRecordDailySpend = checkAndRecordDailySpend;
|
|
|
7
7
|
const fs_1 = __importDefault(require("fs"));
|
|
8
8
|
const os_1 = __importDefault(require("os"));
|
|
9
9
|
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const security_log_js_1 = require("./security-log.js");
|
|
10
11
|
function getBudgetStatePath() {
|
|
11
12
|
const envPath = process.env.ONELY_BUDGET_STATE_FILE;
|
|
12
13
|
if (envPath && envPath.trim().length > 0) {
|
|
@@ -37,7 +38,10 @@ function loadBudgetState() {
|
|
|
37
38
|
function saveBudgetState(state) {
|
|
38
39
|
const filePath = getBudgetStatePath();
|
|
39
40
|
try {
|
|
40
|
-
fs_1.default.writeFileSync(filePath, JSON.stringify(state, null, 2), {
|
|
41
|
+
fs_1.default.writeFileSync(filePath, JSON.stringify(state, null, 2), {
|
|
42
|
+
encoding: "utf-8",
|
|
43
|
+
mode: 0o600, // Owner read/write only (security: prevent other users from reading spending data)
|
|
44
|
+
});
|
|
41
45
|
}
|
|
42
46
|
catch {
|
|
43
47
|
// If we cannot persist, we still allow the call; fail-open is safer for UX
|
|
@@ -53,6 +57,14 @@ function checkAndRecordDailySpend(config, priceUsd) {
|
|
|
53
57
|
const current = state.date === today ? state.spentToday : 0;
|
|
54
58
|
const next = current + priceUsd;
|
|
55
59
|
if (next > config.budgets.daily) {
|
|
60
|
+
// Log budget violation for audit trail
|
|
61
|
+
(0, security_log_js_1.logSecurityEvent)("budget_exceeded", {
|
|
62
|
+
type: "daily",
|
|
63
|
+
currentSpent: current,
|
|
64
|
+
limit: config.budgets.daily,
|
|
65
|
+
attemptedAmount: priceUsd,
|
|
66
|
+
wouldTotal: next,
|
|
67
|
+
});
|
|
56
68
|
throw new Error(`Price $${priceUsd.toFixed(4)} would exceed daily budget of $${config.budgets.daily} (already spent: $${current.toFixed(4)})`);
|
|
57
69
|
}
|
|
58
70
|
const updated = {
|
|
@@ -60,5 +72,11 @@ function checkAndRecordDailySpend(config, priceUsd) {
|
|
|
60
72
|
spentToday: next,
|
|
61
73
|
};
|
|
62
74
|
saveBudgetState(updated);
|
|
75
|
+
// Log successful payment for audit trail
|
|
76
|
+
(0, security_log_js_1.logSecurityEvent)("api_call_paid", {
|
|
77
|
+
amount: priceUsd,
|
|
78
|
+
dailyTotal: next,
|
|
79
|
+
dailyLimit: config.budgets.daily,
|
|
80
|
+
});
|
|
63
81
|
}
|
|
64
82
|
//# sourceMappingURL=budget.js.map
|
package/dist/budget.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"budget.js","sourceRoot":"","sources":["../src/budget.ts"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"budget.js","sourceRoot":"","sources":["../src/budget.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
export declare const ConfigSchema: z.ZodObject<{
|
|
3
|
-
apiBase: z.ZodDefault<z.ZodString
|
|
3
|
+
apiBase: z.ZodDefault<z.ZodEffects<z.ZodString, string, string>>;
|
|
4
4
|
wallet: z.ZodNullable<z.ZodOptional<z.ZodObject<{
|
|
5
5
|
type: z.ZodEnum<["solana", "evm"]>;
|
|
6
6
|
key: z.ZodString;
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8CvB,CAAC;AAEH,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAElD,wBAAgB,UAAU,IAAI,MAAM,CAkEnC;AAED,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,MAAM,CAAC,CAK/D"}
|
package/dist/config.js
CHANGED
|
@@ -5,8 +5,32 @@ exports.loadConfig = loadConfig;
|
|
|
5
5
|
exports.loadConfigWithStoredKey = loadConfigWithStoredKey;
|
|
6
6
|
const zod_1 = require("zod");
|
|
7
7
|
const keys_js_1 = require("./keys.js");
|
|
8
|
+
const security_log_js_1 = require("./security-log.js");
|
|
8
9
|
exports.ConfigSchema = zod_1.z.object({
|
|
9
|
-
apiBase: zod_1.z
|
|
10
|
+
apiBase: zod_1.z
|
|
11
|
+
.string()
|
|
12
|
+
.url()
|
|
13
|
+
.refine((url) => {
|
|
14
|
+
try {
|
|
15
|
+
const parsed = new URL(url);
|
|
16
|
+
// Allow 1ly.store with HTTPS only
|
|
17
|
+
if (parsed.hostname === "1ly.store" || parsed.hostname === "www.1ly.store") {
|
|
18
|
+
return parsed.protocol === "https:";
|
|
19
|
+
}
|
|
20
|
+
// Allow localhost for local development (any port)
|
|
21
|
+
if (parsed.hostname === "localhost" || parsed.hostname === "127.0.0.1") {
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
// Block everything else
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
}, {
|
|
31
|
+
message: "API base must be https://1ly.store or http://localhost:PORT for local development",
|
|
32
|
+
})
|
|
33
|
+
.default("https://1ly.store"),
|
|
10
34
|
wallet: zod_1.z
|
|
11
35
|
.object({
|
|
12
36
|
type: zod_1.z.enum(["solana", "evm"]),
|
|
@@ -17,8 +41,8 @@ exports.ConfigSchema = zod_1.z.object({
|
|
|
17
41
|
walletSolana: zod_1.z.string().optional().nullable(),
|
|
18
42
|
walletEvm: zod_1.z.string().optional().nullable(),
|
|
19
43
|
budgets: zod_1.z.object({
|
|
20
|
-
perCall: zod_1.z.number().positive().default(1.0),
|
|
21
|
-
daily: zod_1.z.number().positive().default(50.0),
|
|
44
|
+
perCall: zod_1.z.number().positive().finite().default(1.0),
|
|
45
|
+
daily: zod_1.z.number().positive().finite().default(50.0),
|
|
22
46
|
}),
|
|
23
47
|
network: zod_1.z.enum(["solana", "base"]).default("solana"),
|
|
24
48
|
apiKey: zod_1.z.string().optional().nullable(),
|
|
@@ -30,18 +54,57 @@ function loadConfig() {
|
|
|
30
54
|
const walletEvm = process.env.ONELY_WALLET_EVM_KEY || null;
|
|
31
55
|
const apiKeyEnv = process.env.ONELY_API_KEY || null;
|
|
32
56
|
const apiBase = process.env.ONELY_API_BASE || "https://1ly.store";
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
57
|
+
// Parse and validate budget values to prevent NaN/negative bypasses
|
|
58
|
+
const perCallRaw = process.env.ONELY_BUDGET_PER_CALL || "1.0";
|
|
59
|
+
const dailyRaw = process.env.ONELY_BUDGET_DAILY || "50.0";
|
|
60
|
+
const perCall = parseFloat(perCallRaw);
|
|
61
|
+
const daily = parseFloat(dailyRaw);
|
|
62
|
+
// Validate parsed values are valid positive numbers
|
|
63
|
+
if (!Number.isFinite(perCall) || perCall <= 0) {
|
|
64
|
+
(0, security_log_js_1.logSecurityEvent)("invalid_budget_config", {
|
|
65
|
+
parameter: "ONELY_BUDGET_PER_CALL",
|
|
66
|
+
value: perCallRaw,
|
|
67
|
+
parsed: perCall,
|
|
68
|
+
});
|
|
69
|
+
throw new Error(`Invalid ONELY_BUDGET_PER_CALL: "${perCallRaw}" - must be a positive number`);
|
|
70
|
+
}
|
|
71
|
+
if (!Number.isFinite(daily) || daily <= 0) {
|
|
72
|
+
(0, security_log_js_1.logSecurityEvent)("invalid_budget_config", {
|
|
73
|
+
parameter: "ONELY_BUDGET_DAILY",
|
|
74
|
+
value: dailyRaw,
|
|
75
|
+
parsed: daily,
|
|
76
|
+
});
|
|
77
|
+
throw new Error(`Invalid ONELY_BUDGET_DAILY: "${dailyRaw}" - must be a positive number`);
|
|
78
|
+
}
|
|
79
|
+
let parsedConfig;
|
|
80
|
+
try {
|
|
81
|
+
parsedConfig = exports.ConfigSchema.parse({
|
|
82
|
+
apiBase,
|
|
83
|
+
wallet: walletType && walletKey ? { type: walletType, key: walletKey } : null,
|
|
84
|
+
walletSolana: walletSolana || (walletType === "solana" ? walletKey : null),
|
|
85
|
+
walletEvm: walletEvm || (walletType === "evm" ? walletKey : null),
|
|
86
|
+
budgets: {
|
|
87
|
+
perCall,
|
|
88
|
+
daily,
|
|
89
|
+
},
|
|
90
|
+
network: process.env.ONELY_NETWORK || "solana",
|
|
91
|
+
apiKey: apiKeyEnv,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
catch (err) {
|
|
95
|
+
// Log API base violations
|
|
96
|
+
if (err instanceof zod_1.z.ZodError) {
|
|
97
|
+
const apiBaseError = err.errors.find((e) => e.path[0] === "apiBase");
|
|
98
|
+
if (apiBaseError) {
|
|
99
|
+
(0, security_log_js_1.logSecurityEvent)("api_base_violation", {
|
|
100
|
+
attempted: apiBase,
|
|
101
|
+
error: apiBaseError.message,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
throw err;
|
|
106
|
+
}
|
|
107
|
+
return parsedConfig;
|
|
45
108
|
}
|
|
46
109
|
async function loadConfigWithStoredKey() {
|
|
47
110
|
const config = loadConfig();
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/http.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export declare class HttpError extends Error {
|
|
|
14
14
|
}
|
|
15
15
|
/**
|
|
16
16
|
* fetchWithTimeout wraps the global fetch with:
|
|
17
|
+
* - rate limiting to prevent abuse
|
|
17
18
|
* - per-request timeout using AbortController
|
|
18
19
|
* - basic retry logic for network/timeout errors
|
|
19
20
|
*/
|
|
@@ -21,6 +22,7 @@ export declare function fetchWithTimeout(url: string, options?: FetchOptions): P
|
|
|
21
22
|
/**
|
|
22
23
|
* Helper to throw a rich HttpError when response.ok is false.
|
|
23
24
|
* Reads a small snippet of the body (if any) for easier debugging.
|
|
25
|
+
* Redacts sensitive information before including in error message.
|
|
24
26
|
*/
|
|
25
27
|
export declare function assertOk(response: Response, contextMessage: string): Promise<void>;
|
|
26
28
|
//# sourceMappingURL=http.d.ts.map
|
package/dist/http.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,YAAa,SAAQ,WAAW;IAC/C,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iEAAiE;IACjE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2DAA2D;IAC3D,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,qBAAa,SAAU,SAAQ,KAAK;aAGhB,MAAM,CAAC,EAAE,MAAM;aACf,GAAG,CAAC,EAAE,MAAM;aACZ,WAAW,CAAC,EAAE,MAAM;gBAHpC,OAAO,EAAE,MAAM,EACC,MAAM,CAAC,EAAE,MAAM,YAAA,EACf,GAAG,CAAC,EAAE,MAAM,YAAA,EACZ,WAAW,CAAC,EAAE,MAAM,YAAA;CAKvC;AAsBD;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,QAAQ,CAAC,CAmDnB;AAED;;;;GAIG;AACH,wBAAsB,QAAQ,CAC5B,QAAQ,EAAE,QAAQ,EAClB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,IAAI,CAAC,CAuBf"}
|
package/dist/http.js
CHANGED
|
@@ -3,9 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.HttpError = void 0;
|
|
4
4
|
exports.fetchWithTimeout = fetchWithTimeout;
|
|
5
5
|
exports.assertOk = assertOk;
|
|
6
|
+
const rate_limit_js_1 = require("./rate-limit.js");
|
|
6
7
|
const DEFAULT_TIMEOUT_MS = 15_000;
|
|
7
8
|
const DEFAULT_RETRIES = 2;
|
|
8
9
|
const DEFAULT_RETRY_DELAY_MS = 500;
|
|
10
|
+
// Global rate limiter: 100 requests per minute to prevent abuse
|
|
11
|
+
const globalRateLimiter = new rate_limit_js_1.RateLimiter(100, 60_000);
|
|
9
12
|
class HttpError extends Error {
|
|
10
13
|
status;
|
|
11
14
|
url;
|
|
@@ -22,12 +25,32 @@ exports.HttpError = HttpError;
|
|
|
22
25
|
function sleep(ms) {
|
|
23
26
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
24
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Redacts sensitive information from error messages
|
|
30
|
+
*/
|
|
31
|
+
function redactSensitive(text) {
|
|
32
|
+
return text
|
|
33
|
+
.replace(/1ly_live_[a-zA-Z0-9]+/g, "1ly_live_***") // API keys
|
|
34
|
+
.replace(/1ly_test_[a-zA-Z0-9]+/g, "1ly_test_***") // Test API keys
|
|
35
|
+
.replace(/[13][a-km-zA-HJ-NP-Z1-9]{25,34}/g, "***") // Bitcoin/Solana addresses
|
|
36
|
+
.replace(/0x[a-fA-F0-9]{40}/g, "0x***") // Ethereum addresses
|
|
37
|
+
.replace(/"apiKey"\s*:\s*"[^"]+"/g, '"apiKey":"***"')
|
|
38
|
+
.replace(/"token"\s*:\s*"[^"]+"/g, '"token":"***"')
|
|
39
|
+
.replace(/"reviewToken"\s*:\s*"[^"]+"/g, '"reviewToken":"***"')
|
|
40
|
+
.replace(/"privateKey"\s*:\s*"[^"]+"/g, '"privateKey":"***"')
|
|
41
|
+
.replace(/"secretKey"\s*:\s*\[[^\]]+\]/g, '"secretKey":"***"');
|
|
42
|
+
}
|
|
25
43
|
/**
|
|
26
44
|
* fetchWithTimeout wraps the global fetch with:
|
|
45
|
+
* - rate limiting to prevent abuse
|
|
27
46
|
* - per-request timeout using AbortController
|
|
28
47
|
* - basic retry logic for network/timeout errors
|
|
29
48
|
*/
|
|
30
49
|
async function fetchWithTimeout(url, options = {}) {
|
|
50
|
+
// Rate limit check
|
|
51
|
+
if (!globalRateLimiter.check()) {
|
|
52
|
+
throw new Error(`Rate limit exceeded: too many requests (max 100 per minute). Current: ${globalRateLimiter.getCurrentCount()}`);
|
|
53
|
+
}
|
|
31
54
|
const { timeoutMs = DEFAULT_TIMEOUT_MS, retries = DEFAULT_RETRIES, retryDelayMs = DEFAULT_RETRY_DELAY_MS, ...fetchOptions } = options;
|
|
32
55
|
let lastError;
|
|
33
56
|
for (let attempt = 0; attempt <= retries; attempt++) {
|
|
@@ -60,6 +83,7 @@ async function fetchWithTimeout(url, options = {}) {
|
|
|
60
83
|
/**
|
|
61
84
|
* Helper to throw a rich HttpError when response.ok is false.
|
|
62
85
|
* Reads a small snippet of the body (if any) for easier debugging.
|
|
86
|
+
* Redacts sensitive information before including in error message.
|
|
63
87
|
*/
|
|
64
88
|
async function assertOk(response, contextMessage) {
|
|
65
89
|
if (response.ok)
|
|
@@ -67,7 +91,9 @@ async function assertOk(response, contextMessage) {
|
|
|
67
91
|
let bodySnippet;
|
|
68
92
|
try {
|
|
69
93
|
const text = await response.text();
|
|
70
|
-
|
|
94
|
+
// Redact sensitive data before including in error
|
|
95
|
+
const redacted = redactSensitive(text.slice(0, 500));
|
|
96
|
+
bodySnippet = redacted;
|
|
71
97
|
}
|
|
72
98
|
catch {
|
|
73
99
|
// Ignore body read errors
|
package/dist/http.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple token bucket rate limiter to prevent API abuse
|
|
3
|
+
* Limits number of requests within a sliding time window
|
|
4
|
+
*/
|
|
5
|
+
export declare class RateLimiter {
|
|
6
|
+
private maxRequests;
|
|
7
|
+
private windowMs;
|
|
8
|
+
private timestamps;
|
|
9
|
+
constructor(maxRequests: number, windowMs: number);
|
|
10
|
+
/**
|
|
11
|
+
* Check if request is allowed. Returns true if allowed, false if rate limit exceeded.
|
|
12
|
+
* Automatically records the request if allowed.
|
|
13
|
+
*/
|
|
14
|
+
check(): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Get current request count within the window
|
|
17
|
+
*/
|
|
18
|
+
getCurrentCount(): number;
|
|
19
|
+
/**
|
|
20
|
+
* Reset the rate limiter
|
|
21
|
+
*/
|
|
22
|
+
reset(): void;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=rate-limit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-limit.d.ts","sourceRoot":"","sources":["../src/rate-limit.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,qBAAa,WAAW;IAIpB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,QAAQ;IAJlB,OAAO,CAAC,UAAU,CAAgB;gBAGxB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM;IAG1B;;;OAGG;IACH,KAAK,IAAI,OAAO;IAiBhB;;OAEG;IACH,eAAe,IAAI,MAAM;IAOzB;;OAEG;IACH,KAAK,IAAI,IAAI;CAGd"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RateLimiter = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Simple token bucket rate limiter to prevent API abuse
|
|
6
|
+
* Limits number of requests within a sliding time window
|
|
7
|
+
*/
|
|
8
|
+
class RateLimiter {
|
|
9
|
+
maxRequests;
|
|
10
|
+
windowMs;
|
|
11
|
+
timestamps = [];
|
|
12
|
+
constructor(maxRequests, windowMs) {
|
|
13
|
+
this.maxRequests = maxRequests;
|
|
14
|
+
this.windowMs = windowMs;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Check if request is allowed. Returns true if allowed, false if rate limit exceeded.
|
|
18
|
+
* Automatically records the request if allowed.
|
|
19
|
+
*/
|
|
20
|
+
check() {
|
|
21
|
+
const now = Date.now();
|
|
22
|
+
const cutoff = now - this.windowMs;
|
|
23
|
+
// Remove timestamps outside the window
|
|
24
|
+
this.timestamps = this.timestamps.filter((t) => t > cutoff);
|
|
25
|
+
// Check if we're at the limit
|
|
26
|
+
if (this.timestamps.length >= this.maxRequests) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
// Record this request
|
|
30
|
+
this.timestamps.push(now);
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Get current request count within the window
|
|
35
|
+
*/
|
|
36
|
+
getCurrentCount() {
|
|
37
|
+
const now = Date.now();
|
|
38
|
+
const cutoff = now - this.windowMs;
|
|
39
|
+
this.timestamps = this.timestamps.filter((t) => t > cutoff);
|
|
40
|
+
return this.timestamps.length;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Reset the rate limiter
|
|
44
|
+
*/
|
|
45
|
+
reset() {
|
|
46
|
+
this.timestamps = [];
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
exports.RateLimiter = RateLimiter;
|
|
50
|
+
//# sourceMappingURL=rate-limit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-limit.js","sourceRoot":"","sources":["../src/rate-limit.ts"],"names":[],"mappings":";;;AAAA;;;GAGG;AACH,MAAa,WAAW;IAIZ;IACA;IAJF,UAAU,GAAa,EAAE,CAAC;IAElC,YACU,WAAmB,EACnB,QAAgB;QADhB,gBAAW,GAAX,WAAW,CAAQ;QACnB,aAAQ,GAAR,QAAQ,CAAQ;IACvB,CAAC;IAEJ;;;OAGG;IACH,KAAK;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC;QAEnC,uCAAuC;QACvC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC;QAE5D,8BAA8B;QAC9B,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YAC/C,OAAO,KAAK,CAAC;QACf,CAAC;QAED,sBAAsB;QACtB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,eAAe;QACb,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC;QACnC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC;QAC5D,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;IAChC,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;IACvB,CAAC;CACF;AA7CD,kCA6CC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Security Event Audit Logging
|
|
3
|
+
*
|
|
4
|
+
* Provides structured logging for security-relevant events to support:
|
|
5
|
+
* - Compliance auditing (SOC 2, ISO 27001)
|
|
6
|
+
* - Security monitoring and alerting
|
|
7
|
+
* - Incident response and forensics
|
|
8
|
+
* - Operational analytics
|
|
9
|
+
*
|
|
10
|
+
* Implementation Notes:
|
|
11
|
+
* - Logs to stderr (stdout reserved for MCP protocol communication)
|
|
12
|
+
* - JSON format for machine readability and SIEM integration
|
|
13
|
+
* - ISO 8601 timestamps for log aggregation
|
|
14
|
+
* - Non-blocking operation
|
|
15
|
+
*
|
|
16
|
+
* @module security-log
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Security event types categorized by domain
|
|
20
|
+
*/
|
|
21
|
+
export type SecurityEventType = "budget_exceeded" | "rate_limit_exceeded" | "wallet_path_violation" | "api_base_violation" | "invalid_budget_config" | "large_upload_blocked" | "api_call_paid" | "store_created" | "withdrawal_requested";
|
|
22
|
+
/**
|
|
23
|
+
* Structured security event log entry
|
|
24
|
+
*/
|
|
25
|
+
export interface SecurityEvent {
|
|
26
|
+
/** ISO 8601 timestamp */
|
|
27
|
+
timestamp: string;
|
|
28
|
+
/** Event type identifier */
|
|
29
|
+
event: SecurityEventType;
|
|
30
|
+
/** Event-specific contextual data */
|
|
31
|
+
details: Record<string, unknown>;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Log a security-relevant event for audit trail
|
|
35
|
+
*
|
|
36
|
+
* Events are written to stderr in JSON format for:
|
|
37
|
+
* - Log aggregation systems (Datadog, Splunk, ELK)
|
|
38
|
+
* - SIEM platforms
|
|
39
|
+
* - Compliance reporting
|
|
40
|
+
*
|
|
41
|
+
* @param event - Event type identifier
|
|
42
|
+
* @param details - Event-specific contextual information
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```typescript
|
|
46
|
+
* logSecurityEvent("budget_exceeded", {
|
|
47
|
+
* type: "daily",
|
|
48
|
+
* currentSpent: 48.50,
|
|
49
|
+
* limit: 50.00,
|
|
50
|
+
* attemptedAmount: 2.00
|
|
51
|
+
* });
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
export declare function logSecurityEvent(event: SecurityEventType, details?: Record<string, unknown>): void;
|
|
55
|
+
//# sourceMappingURL=security-log.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security-log.d.ts","sourceRoot":"","sources":["../src/security-log.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAEzB,iBAAiB,GACjB,qBAAqB,GAErB,uBAAuB,GACvB,oBAAoB,GACpB,uBAAuB,GAEvB,sBAAsB,GAEtB,eAAe,GACf,eAAe,GACf,sBAAsB,CAAC;AAE3B;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,yBAAyB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,4BAA4B;IAC5B,KAAK,EAAE,iBAAiB,CAAC;IACzB,qCAAqC;IACrC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,iBAAiB,EACxB,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACpC,IAAI,CAUN"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Security Event Audit Logging
|
|
4
|
+
*
|
|
5
|
+
* Provides structured logging for security-relevant events to support:
|
|
6
|
+
* - Compliance auditing (SOC 2, ISO 27001)
|
|
7
|
+
* - Security monitoring and alerting
|
|
8
|
+
* - Incident response and forensics
|
|
9
|
+
* - Operational analytics
|
|
10
|
+
*
|
|
11
|
+
* Implementation Notes:
|
|
12
|
+
* - Logs to stderr (stdout reserved for MCP protocol communication)
|
|
13
|
+
* - JSON format for machine readability and SIEM integration
|
|
14
|
+
* - ISO 8601 timestamps for log aggregation
|
|
15
|
+
* - Non-blocking operation
|
|
16
|
+
*
|
|
17
|
+
* @module security-log
|
|
18
|
+
*/
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.logSecurityEvent = logSecurityEvent;
|
|
21
|
+
/**
|
|
22
|
+
* Log a security-relevant event for audit trail
|
|
23
|
+
*
|
|
24
|
+
* Events are written to stderr in JSON format for:
|
|
25
|
+
* - Log aggregation systems (Datadog, Splunk, ELK)
|
|
26
|
+
* - SIEM platforms
|
|
27
|
+
* - Compliance reporting
|
|
28
|
+
*
|
|
29
|
+
* @param event - Event type identifier
|
|
30
|
+
* @param details - Event-specific contextual information
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```typescript
|
|
34
|
+
* logSecurityEvent("budget_exceeded", {
|
|
35
|
+
* type: "daily",
|
|
36
|
+
* currentSpent: 48.50,
|
|
37
|
+
* limit: 50.00,
|
|
38
|
+
* attemptedAmount: 2.00
|
|
39
|
+
* });
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
function logSecurityEvent(event, details = {}) {
|
|
43
|
+
const entry = {
|
|
44
|
+
timestamp: new Date().toISOString(),
|
|
45
|
+
event,
|
|
46
|
+
details,
|
|
47
|
+
};
|
|
48
|
+
// Write to stderr (stdout is MCP protocol channel)
|
|
49
|
+
// Using console.error for non-blocking write
|
|
50
|
+
console.error(JSON.stringify(entry));
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=security-log.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security-log.js","sourceRoot":"","sources":["../src/security-log.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;GAgBG;;AAqDH,4CAaC;AAlCD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,SAAgB,gBAAgB,CAC9B,KAAwB,EACxB,UAAmC,EAAE;IAErC,MAAM,KAAK,GAAkB;QAC3B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,KAAK;QACL,OAAO;KACR,CAAC;IAEF,mDAAmD;IACnD,6CAA6C;IAC7C,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;AACvC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update-avatar.d.ts","sourceRoot":"","sources":["../../src/tools/update-avatar.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAI3C,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;CAY5B,CAAC;
|
|
1
|
+
{"version":3,"file":"update-avatar.d.ts","sourceRoot":"","sources":["../../src/tools/update-avatar.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAI3C,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;CAY5B,CAAC;AAmBF,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM;;;;;;GA6DrE"}
|
|
@@ -20,9 +20,19 @@ exports.updateAvatarTool = {
|
|
|
20
20
|
};
|
|
21
21
|
const InputSchema = zod_1.z.object({
|
|
22
22
|
avatarUrl: zod_1.z.string().url().optional(),
|
|
23
|
-
imageBase64: zod_1.z
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
imageBase64: zod_1.z
|
|
24
|
+
.string()
|
|
25
|
+
.min(1)
|
|
26
|
+
.max(10_485_760) // 10MB max (base64 encoded ~= 1.37x original size)
|
|
27
|
+
.optional(),
|
|
28
|
+
mimeType: zod_1.z
|
|
29
|
+
.enum(["image/png", "image/jpeg", "image/jpg", "image/webp", "image/gif"]) // Strict MIME type validation
|
|
30
|
+
.optional(),
|
|
31
|
+
filename: zod_1.z
|
|
32
|
+
.string()
|
|
33
|
+
.regex(/^[a-zA-Z0-9_.-]+$/) // Prevent path traversal in filename
|
|
34
|
+
.max(255)
|
|
35
|
+
.optional(),
|
|
26
36
|
});
|
|
27
37
|
async function handleUpdateAvatar(args, config) {
|
|
28
38
|
const input = InputSchema.parse(args);
|
|
@@ -45,7 +55,23 @@ async function handleUpdateAvatar(args, config) {
|
|
|
45
55
|
if (!input.imageBase64 || !input.mimeType) {
|
|
46
56
|
throw new Error("Provide either avatarUrl or imageBase64 + mimeType");
|
|
47
57
|
}
|
|
48
|
-
|
|
58
|
+
// Decode and validate base64
|
|
59
|
+
let buffer;
|
|
60
|
+
try {
|
|
61
|
+
buffer = Buffer.from(input.imageBase64, "base64");
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
throw new Error("Invalid base64 encoding");
|
|
65
|
+
}
|
|
66
|
+
// Validate decoded size (5MB max for actual image data)
|
|
67
|
+
const maxSize = 5 * 1024 * 1024; // 5MB
|
|
68
|
+
if (buffer.length > maxSize) {
|
|
69
|
+
throw new Error(`Image size ${(buffer.length / 1024 / 1024).toFixed(2)}MB exceeds 5MB limit`);
|
|
70
|
+
}
|
|
71
|
+
// Minimum size check (prevent empty uploads)
|
|
72
|
+
if (buffer.length < 100) {
|
|
73
|
+
throw new Error("Image too small - minimum 100 bytes");
|
|
74
|
+
}
|
|
49
75
|
const blob = new Blob([buffer], { type: input.mimeType });
|
|
50
76
|
const formData = new FormData();
|
|
51
77
|
formData.append("file", blob, input.filename || "avatar.png");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update-avatar.js","sourceRoot":"","sources":["../../src/tools/update-avatar.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"update-avatar.js","sourceRoot":"","sources":["../../src/tools/update-avatar.ts"],"names":[],"mappings":"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"}
|
package/dist/wallet/evm.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"evm.d.ts","sourceRoot":"","sources":["../../src/wallet/evm.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,iBAAiB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"evm.d.ts","sourceRoot":"","sources":["../../src/wallet/evm.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAQ5E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAqCxD,wBAAsB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAgBhF;AAED,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAG3E;AAED,UAAU,mBAAmB;IAC3B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,OAAO;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,KAAK,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACjC,CAAC,CAAC;IACH,QAAQ,CAAC,EAAE;QACT,GAAG,EAAE,MAAM,CAAC;QACZ,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAaD;;;GAGG;AACH,wBAAsB,eAAe,CACnC,YAAY,EAAE,mBAAmB,EACjC,OAAO,EAAE,iBAAiB,EAC1B,OAAO,CAAC,EAAE,OAAO,GAChB,OAAO,CAAC,MAAM,CAAC,CAmEjB;AAYD,wBAAsB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,iBAAiB,CAAC;IAAC,UAAU,EAAE,KAAK,MAAM,EAAE,CAAA;CAAE,CAAC,CAiB/H;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,YAAY,EAAE,mBAAmB,EACjC,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,OAAO,GAChB,OAAO,CAAC,MAAM,CAAC,CAmDjB;AAED,wBAAsB,wBAAwB,CAC5C,eAAe,EAAE,eAAe,EAChC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC,CAqCjB"}
|
package/dist/wallet/evm.js
CHANGED
|
@@ -41,18 +41,50 @@ exports.buildEvmPaymentSimple = buildEvmPaymentSimple;
|
|
|
41
41
|
exports.buildEvmPaymentSignature = buildEvmPaymentSignature;
|
|
42
42
|
const accounts_1 = require("viem/accounts");
|
|
43
43
|
const chains_1 = require("viem/chains");
|
|
44
|
+
const path_1 = require("path");
|
|
45
|
+
const os = __importStar(require("os"));
|
|
44
46
|
const client_1 = require("@x402/core/client");
|
|
45
47
|
const http_1 = require("@x402/core/http");
|
|
46
48
|
const evm_1 = require("@x402/evm");
|
|
47
49
|
const fs = __importStar(require("fs"));
|
|
48
50
|
// Mainnet only
|
|
49
51
|
const CHAIN = chains_1.base;
|
|
52
|
+
/**
|
|
53
|
+
* Validates wallet file path to prevent directory traversal attacks.
|
|
54
|
+
* Only allows files in home directory or /tmp (for testing).
|
|
55
|
+
*/
|
|
56
|
+
function validateWalletPath(keyPath) {
|
|
57
|
+
try {
|
|
58
|
+
const normalizedPath = (0, path_1.normalize)((0, path_1.resolve)(keyPath));
|
|
59
|
+
const homeDir = os.homedir();
|
|
60
|
+
// Allow files in home directory or /tmp
|
|
61
|
+
const isInHome = normalizedPath.startsWith(homeDir);
|
|
62
|
+
const isInTmp = normalizedPath.startsWith("/tmp") || normalizedPath.startsWith(os.tmpdir());
|
|
63
|
+
if (!isInHome && !isInTmp) {
|
|
64
|
+
throw new Error("Wallet file must be in home directory or /tmp for security. Path: " + normalizedPath);
|
|
65
|
+
}
|
|
66
|
+
// Block sensitive directories
|
|
67
|
+
const blockedPaths = [".ssh", ".gnupg", ".aws", ".kube"];
|
|
68
|
+
if (blockedPaths.some((p) => normalizedPath.includes(`/${p}/`))) {
|
|
69
|
+
throw new Error("Cannot load wallet from sensitive directory");
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
if (err instanceof Error && err.message.includes("Wallet file must be")) {
|
|
74
|
+
throw err;
|
|
75
|
+
}
|
|
76
|
+
throw new Error("Invalid wallet file path");
|
|
77
|
+
}
|
|
78
|
+
}
|
|
50
79
|
async function loadEvmWallet(keyInput) {
|
|
51
80
|
let privateKey;
|
|
52
81
|
if (keyInput.startsWith("0x")) {
|
|
82
|
+
// Inline hex key - no path validation needed
|
|
53
83
|
privateKey = keyInput;
|
|
54
84
|
}
|
|
55
85
|
else if (fs.existsSync(keyInput)) {
|
|
86
|
+
// File path - validate before reading
|
|
87
|
+
validateWalletPath(keyInput);
|
|
56
88
|
const content = fs.readFileSync(keyInput, "utf-8").trim();
|
|
57
89
|
privateKey = (content.startsWith("0x") ? content : `0x${content}`);
|
|
58
90
|
}
|
|
@@ -141,9 +173,12 @@ let storedPrivateKey = null;
|
|
|
141
173
|
async function loadEvmWalletWithKey(keyInput) {
|
|
142
174
|
let privateKey;
|
|
143
175
|
if (keyInput.startsWith("0x")) {
|
|
176
|
+
// Inline hex key - no path validation needed
|
|
144
177
|
privateKey = keyInput;
|
|
145
178
|
}
|
|
146
179
|
else if (fs.existsSync(keyInput)) {
|
|
180
|
+
// File path - validate before reading
|
|
181
|
+
validateWalletPath(keyInput);
|
|
147
182
|
const content = fs.readFileSync(keyInput, "utf-8").trim();
|
|
148
183
|
privateKey = (content.startsWith("0x") ? content : `0x${content}`);
|
|
149
184
|
}
|
package/dist/wallet/evm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"evm.js","sourceRoot":"","sources":["../../src/wallet/evm.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"evm.js","sourceRoot":"","sources":["../../src/wallet/evm.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"solana.d.ts","sourceRoot":"","sources":["../../src/wallet/solana.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"solana.d.ts","sourceRoot":"","sources":["../../src/wallet/solana.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAS1C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAkCxD,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CA2BxE;AAED,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,QAAQ,GAAG,KAAK,EACtB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,MAAM,CAAC,CAMjB;AAED,wBAAsB,2BAA2B,CAC/C,eAAe,EAAE,eAAe,EAChC,MAAM,EAAE,OAAO,GACd,OAAO,CAAC,MAAM,CAAC,CAqBjB"}
|
package/dist/wallet/solana.js
CHANGED
|
@@ -38,17 +38,49 @@ exports.getWalletAddress = getWalletAddress;
|
|
|
38
38
|
exports.buildSolanaPaymentSignature = buildSolanaPaymentSignature;
|
|
39
39
|
const web3_js_1 = require("@solana/web3.js");
|
|
40
40
|
const fs = __importStar(require("fs"));
|
|
41
|
+
const path_1 = require("path");
|
|
42
|
+
const os = __importStar(require("os"));
|
|
41
43
|
const client_1 = require("@x402/core/client");
|
|
42
44
|
const http_1 = require("@x402/core/http");
|
|
43
45
|
const client_2 = require("@x402/svm/exact/client");
|
|
44
46
|
const svm_1 = require("@x402/svm");
|
|
45
47
|
const signers_1 = require("@solana/signers");
|
|
48
|
+
/**
|
|
49
|
+
* Validates wallet file path to prevent directory traversal attacks.
|
|
50
|
+
* Only allows files in home directory or /tmp (for testing).
|
|
51
|
+
*/
|
|
52
|
+
function validateWalletPath(keyPath) {
|
|
53
|
+
try {
|
|
54
|
+
const normalizedPath = (0, path_1.normalize)((0, path_1.resolve)(keyPath));
|
|
55
|
+
const homeDir = os.homedir();
|
|
56
|
+
// Allow files in home directory or /tmp
|
|
57
|
+
const isInHome = normalizedPath.startsWith(homeDir);
|
|
58
|
+
const isInTmp = normalizedPath.startsWith("/tmp") || normalizedPath.startsWith(os.tmpdir());
|
|
59
|
+
if (!isInHome && !isInTmp) {
|
|
60
|
+
throw new Error("Wallet file must be in home directory or /tmp for security. Path: " + normalizedPath);
|
|
61
|
+
}
|
|
62
|
+
// Block sensitive directories
|
|
63
|
+
const blockedPaths = [".ssh", ".gnupg", ".aws", ".kube"];
|
|
64
|
+
if (blockedPaths.some((p) => normalizedPath.includes(`/${p}/`))) {
|
|
65
|
+
throw new Error("Cannot load wallet from sensitive directory");
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
if (err instanceof Error && err.message.includes("Wallet file must be")) {
|
|
70
|
+
throw err;
|
|
71
|
+
}
|
|
72
|
+
throw new Error("Invalid wallet file path");
|
|
73
|
+
}
|
|
74
|
+
}
|
|
46
75
|
async function loadSolanaWallet(keyPath) {
|
|
47
76
|
let keyData;
|
|
48
77
|
if (keyPath.startsWith("[")) {
|
|
78
|
+
// Inline JSON array format - no path validation needed
|
|
49
79
|
keyData = JSON.parse(keyPath);
|
|
50
80
|
}
|
|
51
81
|
else if (fs.existsSync(keyPath)) {
|
|
82
|
+
// File path - validate before reading
|
|
83
|
+
validateWalletPath(keyPath);
|
|
52
84
|
const fileContent = fs.readFileSync(keyPath, "utf-8");
|
|
53
85
|
const parsed = JSON.parse(fileContent);
|
|
54
86
|
// Handle both formats:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"solana.js","sourceRoot":"","sources":["../../src/wallet/solana.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"solana.js","sourceRoot":"","sources":["../../src/wallet/solana.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2CA,4CA2BC;AAED,4CASC;AAED,kEAwBC;AA3GD,6CAA0C;AAC1C,uCAAyB;AACzB,+BAA0C;AAC1C,uCAAyB;AACzB,8CAA+C;AAC/C,0CAAiD;AACjD,mDAAgE;AAChE,mCAA8C;AAC9C,6CAA+D;AAG/D;;;GAGG;AACH,SAAS,kBAAkB,CAAC,OAAe;IACzC,IAAI,CAAC;QACH,MAAM,cAAc,GAAG,IAAA,gBAAS,EAAC,IAAA,cAAO,EAAC,OAAO,CAAC,CAAC,CAAC;QACnD,MAAM,OAAO,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC;QAE7B,wCAAwC;QACxC,MAAM,QAAQ,GAAG,cAAc,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QACpD,MAAM,OAAO,GAAG,cAAc,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,cAAc,CAAC,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;QAE5F,IAAI,CAAC,QAAQ,IAAI,CAAC,OAAO,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CACb,oEAAoE,GAAG,cAAc,CACtF,CAAC;QACJ,CAAC;QAED,8BAA8B;QAC9B,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;QACzD,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YAChE,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;QACjE,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,KAAK,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,CAAC;YACxE,MAAM,GAAG,CAAC;QACZ,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAC9C,CAAC;AACH,CAAC;AAEM,KAAK,UAAU,gBAAgB,CAAC,OAAe;IACpD,IAAI,OAAiB,CAAC;IAEtB,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5B,uDAAuD;QACvD,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;SAAM,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAClC,sCAAsC;QACtC,kBAAkB,CAAC,OAAO,CAAC,CAAC;QAC5B,MAAM,WAAW,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACtD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAEvC,uBAAuB;QACvB,iEAAiE;QACjE,4CAA4C;QAC5C,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1B,OAAO,GAAG,MAAM,CAAC;QACnB,CAAC;aAAM,IAAI,MAAM,CAAC,SAAS,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;YAC/D,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC;QAC7B,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,KAAK,CAAC,8BAA8B,OAAO,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED,OAAO,iBAAO,CAAC,aAAa,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;AACzD,CAAC;AAEM,KAAK,UAAU,gBAAgB,CACpC,IAAsB,EACtB,GAAW;IAEX,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,GAAG,CAAC,CAAC;QAC3C,OAAO,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;IACrC,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;AACpD,CAAC;AAEM,KAAK,UAAU,2BAA2B,CAC/C,eAAgC,EAChC,MAAe;IAEf,MAAM,MAAM,GAAG,MAAM,IAAA,sCAA4B,EAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACpE,MAAM,SAAS,GAAG,IAAA,uBAAiB,EAAC,MAAM,CAAC,CAAC;IAC5C,MAAM,UAAU,GAAG,IAAI,mBAAU,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE;QAC/C,OAAO,CACL,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;YACpE,OAAO,CAAC,CAAC,CAAC,CACX,CAAC;IACJ,CAAC,CAAC,CAAC;IACH,IAAA,+BAAsB,EAAC,UAAU,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;IAC1D,MAAM,UAAU,GAAG,IAAI,qBAAc,CAAC,UAAU,CAAC,CAAC;IAClD,MAAM,cAAc,GAAG,MAAM,UAAU,CAAC,oBAAoB,CAAC,eAAe,CAAC,CAAC;IAC9E,MAAM,OAAO,GAAG,UAAU,CAAC,4BAA4B,CAAC,cAAc,CAAC,CAAC;IAExE,OAAO,CACL,OAAO,CAAC,mBAAmB,CAAC;QAC5B,OAAO,CAAC,mBAAmB,CAAC;QAC5B,OAAO,CAAC,mBAAmB,CAAC;QAC5B,OAAO,CAAC,WAAW,CAAC;QACpB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAC/D,CAAC;AACJ,CAAC"}
|