@x402scan/mcp 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +2201 -9
- package/dist/index.js.map +1 -0
- package/package.json +6 -6
- package/dist/chunk-FFXFOKKF.js +0 -267
- package/dist/chunk-KD3GRRAV.js +0 -43
- package/dist/fund-743A34XB.js +0 -19
- package/dist/install-QDUD2KOS.js +0 -646
- package/dist/server-CD4OSIVL.js +0 -1109
package/dist/chunk-FFXFOKKF.js
DELETED
|
@@ -1,267 +0,0 @@
|
|
|
1
|
-
// src/lib/log.ts
|
|
2
|
-
import { appendFileSync, mkdirSync } from "fs";
|
|
3
|
-
import { join } from "path";
|
|
4
|
-
import { homedir } from "os";
|
|
5
|
-
var LOG_DIR = join(homedir(), ".x402scan-mcp");
|
|
6
|
-
var LOG_FILE = join(LOG_DIR, "mcp.log");
|
|
7
|
-
var DEBUG = process.env.X402_DEBUG === "true";
|
|
8
|
-
try {
|
|
9
|
-
mkdirSync(LOG_DIR, { recursive: true });
|
|
10
|
-
} catch {
|
|
11
|
-
}
|
|
12
|
-
function format(args) {
|
|
13
|
-
return args.map(
|
|
14
|
-
(a) => typeof a === "object" && a !== null ? JSON.stringify(a) : String(a)
|
|
15
|
-
).join(" ");
|
|
16
|
-
}
|
|
17
|
-
function write(level, msg, args) {
|
|
18
|
-
const formatted = args.length ? `${msg} ${format(args)}` : msg;
|
|
19
|
-
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] [${level}] ${formatted}
|
|
20
|
-
`;
|
|
21
|
-
try {
|
|
22
|
-
appendFileSync(LOG_FILE, line);
|
|
23
|
-
} catch {
|
|
24
|
-
}
|
|
25
|
-
if (process.env.X402_DEBUG === "true") {
|
|
26
|
-
console.error(`[x402scan] ${formatted}`);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
var log = {
|
|
30
|
-
info: (msg, ...args) => write("INFO", msg, args),
|
|
31
|
-
error: (msg, ...args) => write("ERROR", msg, args),
|
|
32
|
-
debug: (msg, ...args) => DEBUG && write("DEBUG", msg, args),
|
|
33
|
-
path: LOG_FILE
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
// src/lib/deposit.ts
|
|
37
|
-
import boxen from "boxen";
|
|
38
|
-
import chalk from "chalk";
|
|
39
|
-
import { select, log as log2 } from "@clack/prompts";
|
|
40
|
-
import open from "open";
|
|
41
|
-
|
|
42
|
-
// src/lib/networks.ts
|
|
43
|
-
import {
|
|
44
|
-
base,
|
|
45
|
-
baseSepolia,
|
|
46
|
-
mainnet,
|
|
47
|
-
sepolia,
|
|
48
|
-
optimism,
|
|
49
|
-
arbitrum,
|
|
50
|
-
polygon
|
|
51
|
-
} from "viem/chains";
|
|
52
|
-
var CHAIN_CONFIGS = {
|
|
53
|
-
"eip155:8453": {
|
|
54
|
-
chain: base,
|
|
55
|
-
caip2: "eip155:8453",
|
|
56
|
-
v1Name: "base",
|
|
57
|
-
usdcAddress: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
|
|
58
|
-
},
|
|
59
|
-
"eip155:84532": {
|
|
60
|
-
chain: baseSepolia,
|
|
61
|
-
caip2: "eip155:84532",
|
|
62
|
-
v1Name: "base-sepolia",
|
|
63
|
-
usdcAddress: "0x036CbD53842c5426634e7929541eC2318f3dCF7e"
|
|
64
|
-
},
|
|
65
|
-
"eip155:1": {
|
|
66
|
-
chain: mainnet,
|
|
67
|
-
caip2: "eip155:1",
|
|
68
|
-
v1Name: "ethereum",
|
|
69
|
-
usdcAddress: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
|
|
70
|
-
},
|
|
71
|
-
"eip155:11155111": {
|
|
72
|
-
chain: sepolia,
|
|
73
|
-
caip2: "eip155:11155111",
|
|
74
|
-
v1Name: "ethereum-sepolia",
|
|
75
|
-
usdcAddress: "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238"
|
|
76
|
-
},
|
|
77
|
-
"eip155:10": {
|
|
78
|
-
chain: optimism,
|
|
79
|
-
caip2: "eip155:10",
|
|
80
|
-
v1Name: "optimism",
|
|
81
|
-
usdcAddress: "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85"
|
|
82
|
-
},
|
|
83
|
-
"eip155:42161": {
|
|
84
|
-
chain: arbitrum,
|
|
85
|
-
caip2: "eip155:42161",
|
|
86
|
-
v1Name: "arbitrum",
|
|
87
|
-
usdcAddress: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831"
|
|
88
|
-
},
|
|
89
|
-
"eip155:137": {
|
|
90
|
-
chain: polygon,
|
|
91
|
-
caip2: "eip155:137",
|
|
92
|
-
v1Name: "polygon",
|
|
93
|
-
usdcAddress: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359"
|
|
94
|
-
}
|
|
95
|
-
};
|
|
96
|
-
var V1_TO_CAIP2 = {
|
|
97
|
-
base: "eip155:8453",
|
|
98
|
-
"base-sepolia": "eip155:84532",
|
|
99
|
-
ethereum: "eip155:1",
|
|
100
|
-
"ethereum-sepolia": "eip155:11155111",
|
|
101
|
-
optimism: "eip155:10",
|
|
102
|
-
arbitrum: "eip155:42161",
|
|
103
|
-
polygon: "eip155:137"
|
|
104
|
-
};
|
|
105
|
-
var DEFAULT_NETWORK = "eip155:8453";
|
|
106
|
-
function toCaip2(network) {
|
|
107
|
-
if (network.startsWith("eip155:")) return network;
|
|
108
|
-
return V1_TO_CAIP2[network.toLowerCase()] ?? network;
|
|
109
|
-
}
|
|
110
|
-
function getChainConfig(network) {
|
|
111
|
-
return CHAIN_CONFIGS[toCaip2(network)];
|
|
112
|
-
}
|
|
113
|
-
function getUSDCAddress(network) {
|
|
114
|
-
return getChainConfig(network)?.usdcAddress;
|
|
115
|
-
}
|
|
116
|
-
function getChain(network) {
|
|
117
|
-
return getChainConfig(network)?.chain;
|
|
118
|
-
}
|
|
119
|
-
function getChainName(network) {
|
|
120
|
-
return getChainConfig(network)?.chain.name ?? network;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// src/lib/wait.ts
|
|
124
|
-
import { spinner } from "@clack/prompts";
|
|
125
|
-
var wait = async ({ startText, stopText, ms }) => {
|
|
126
|
-
const { start: startSpinner, stop: stopSpinner } = spinner();
|
|
127
|
-
startSpinner(startText);
|
|
128
|
-
await new Promise((resolve) => setTimeout(resolve, ms));
|
|
129
|
-
stopSpinner(stopText);
|
|
130
|
-
};
|
|
131
|
-
|
|
132
|
-
// src/lib/deposit.ts
|
|
133
|
-
var getDepositLink = (address, flags) => {
|
|
134
|
-
const baseUrl = flags.dev ? "http://localhost:3000" : "https://x402scan.com";
|
|
135
|
-
return `${baseUrl}/deposit/${address}`;
|
|
136
|
-
};
|
|
137
|
-
var openDepositLink = async (address, flags) => {
|
|
138
|
-
const depositLink = getDepositLink(address, flags);
|
|
139
|
-
await open(depositLink);
|
|
140
|
-
};
|
|
141
|
-
var promptDeposit = async (address, flags) => {
|
|
142
|
-
const depositLink = getDepositLink(address, flags);
|
|
143
|
-
const guidedDeposit = await select({
|
|
144
|
-
message: chalk.bold("How would you like to deposit?"),
|
|
145
|
-
initialValue: true,
|
|
146
|
-
options: [
|
|
147
|
-
{
|
|
148
|
-
label: `Guided - Recommended`,
|
|
149
|
-
value: true,
|
|
150
|
-
hint: "Online portal in x402scan"
|
|
151
|
-
},
|
|
152
|
-
{
|
|
153
|
-
label: "Manual",
|
|
154
|
-
value: false,
|
|
155
|
-
hint: "Print deposit instructions"
|
|
156
|
-
},
|
|
157
|
-
{
|
|
158
|
-
label: "Skip",
|
|
159
|
-
value: void 0,
|
|
160
|
-
hint: "Skip deposit process - functionality limited"
|
|
161
|
-
}
|
|
162
|
-
]
|
|
163
|
-
});
|
|
164
|
-
if (guidedDeposit === true) {
|
|
165
|
-
await wait({
|
|
166
|
-
startText: "Opening deposit page...",
|
|
167
|
-
stopText: `Opening ${chalk.underline.hex("#2563eb")(depositLink)}`,
|
|
168
|
-
ms: 1e3
|
|
169
|
-
});
|
|
170
|
-
await open(depositLink);
|
|
171
|
-
} else if (guidedDeposit === false) {
|
|
172
|
-
log2.message(
|
|
173
|
-
boxen(
|
|
174
|
-
`${chalk.bold("Account Information")}
|
|
175
|
-
Address: ${address}
|
|
176
|
-
Network: ${getChainName(DEFAULT_NETWORK)}
|
|
177
|
-
|
|
178
|
-
${chalk.bold("Online Portal")}
|
|
179
|
-
${chalk.underline(depositLink)}`,
|
|
180
|
-
{
|
|
181
|
-
borderStyle: "round",
|
|
182
|
-
borderColor: "#2563eb",
|
|
183
|
-
title: "Deposit Instructions",
|
|
184
|
-
padding: 1
|
|
185
|
-
}
|
|
186
|
-
)
|
|
187
|
-
);
|
|
188
|
-
}
|
|
189
|
-
};
|
|
190
|
-
|
|
191
|
-
// src/lib/wallet.ts
|
|
192
|
-
import z2 from "zod";
|
|
193
|
-
import { randomBytes } from "crypto";
|
|
194
|
-
import * as fs from "fs/promises";
|
|
195
|
-
import { join as join2 } from "path";
|
|
196
|
-
import { homedir as homedir2 } from "os";
|
|
197
|
-
import { privateKeyToAccount } from "viem/accounts";
|
|
198
|
-
|
|
199
|
-
// src/server/lib/schemas.ts
|
|
200
|
-
import z from "zod";
|
|
201
|
-
import { getAddress } from "viem";
|
|
202
|
-
var ethereumAddressSchema = z.string().regex(/^0x[a-fA-F0-9]{40}$/, "Invalid Ethereum address").transform((address) => getAddress(address));
|
|
203
|
-
var ethereumPrivateKeySchema = z.string().regex(/^0x[a-fA-F0-9]{64}$/, "Invalid Ethereum private key").transform((privateKey) => privateKey);
|
|
204
|
-
var requestSchema = z.object({
|
|
205
|
-
url: z.url().describe("The endpoint URL"),
|
|
206
|
-
method: z.enum(["GET", "POST", "PUT", "DELETE", "PATCH"]).default("GET").describe("HTTP method"),
|
|
207
|
-
body: z.unknown().optional().describe("Request body for POST/PUT/PATCH methods")
|
|
208
|
-
});
|
|
209
|
-
var requestWithHeadersSchema = requestSchema.extend({
|
|
210
|
-
headers: z.record(z.string(), z.string()).optional().describe("Additional headers to include").default({})
|
|
211
|
-
});
|
|
212
|
-
|
|
213
|
-
// src/lib/wallet.ts
|
|
214
|
-
var KEYSTORE_DIR = join2(homedir2(), ".x402scan-mcp");
|
|
215
|
-
var KEYSTORE_FILE = join2(KEYSTORE_DIR, "wallet.json");
|
|
216
|
-
var storedWalletSchema = z2.object({
|
|
217
|
-
privateKey: ethereumPrivateKeySchema,
|
|
218
|
-
address: ethereumAddressSchema,
|
|
219
|
-
createdAt: z2.string()
|
|
220
|
-
});
|
|
221
|
-
async function getWallet() {
|
|
222
|
-
if (process.env.X402_PRIVATE_KEY) {
|
|
223
|
-
const account2 = privateKeyToAccount(process.env.X402_PRIVATE_KEY);
|
|
224
|
-
log.info(`Using wallet from env: ${account2.address}`);
|
|
225
|
-
return { account: account2, isNew: false };
|
|
226
|
-
}
|
|
227
|
-
try {
|
|
228
|
-
const data = await fs.readFile(KEYSTORE_FILE, "utf-8");
|
|
229
|
-
const stored2 = storedWalletSchema.parse(JSON.parse(data));
|
|
230
|
-
const account2 = privateKeyToAccount(stored2.privateKey);
|
|
231
|
-
log.info(`Loaded wallet: ${account2.address}`);
|
|
232
|
-
return { account: account2, isNew: false };
|
|
233
|
-
} catch {
|
|
234
|
-
}
|
|
235
|
-
const privateKey = `0x${randomBytes(32).toString("hex")}`;
|
|
236
|
-
const account = privateKeyToAccount(privateKey);
|
|
237
|
-
const stored = {
|
|
238
|
-
privateKey,
|
|
239
|
-
address: account.address,
|
|
240
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
241
|
-
};
|
|
242
|
-
await fs.mkdir(KEYSTORE_DIR, { recursive: true });
|
|
243
|
-
await fs.writeFile(KEYSTORE_FILE, JSON.stringify(stored, null, 2));
|
|
244
|
-
try {
|
|
245
|
-
await fs.chmod(KEYSTORE_FILE, 384);
|
|
246
|
-
} catch {
|
|
247
|
-
}
|
|
248
|
-
log.info(`Created wallet: ${account.address}`);
|
|
249
|
-
log.info(`Saved to: ${KEYSTORE_FILE}`);
|
|
250
|
-
return { account, isNew: true };
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
export {
|
|
254
|
-
requestSchema,
|
|
255
|
-
requestWithHeadersSchema,
|
|
256
|
-
log,
|
|
257
|
-
DEFAULT_NETWORK,
|
|
258
|
-
toCaip2,
|
|
259
|
-
getUSDCAddress,
|
|
260
|
-
getChain,
|
|
261
|
-
getChainName,
|
|
262
|
-
wait,
|
|
263
|
-
getDepositLink,
|
|
264
|
-
openDepositLink,
|
|
265
|
-
promptDeposit,
|
|
266
|
-
getWallet
|
|
267
|
-
};
|
package/dist/chunk-KD3GRRAV.js
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
DEFAULT_NETWORK,
|
|
3
|
-
getChain,
|
|
4
|
-
getUSDCAddress,
|
|
5
|
-
log,
|
|
6
|
-
toCaip2
|
|
7
|
-
} from "./chunk-FFXFOKKF.js";
|
|
8
|
-
|
|
9
|
-
// src/lib/token.ts
|
|
10
|
-
import { formatUnits } from "viem";
|
|
11
|
-
var tokenBigIntToNumber = (amount, decimals = 6) => {
|
|
12
|
-
return Number(formatUnits(amount, decimals));
|
|
13
|
-
};
|
|
14
|
-
var tokenStringToNumber = (amount, decimals = 6) => {
|
|
15
|
-
return tokenBigIntToNumber(BigInt(amount), decimals);
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
// src/lib/balance.ts
|
|
19
|
-
import { createPublicClient, http, erc20Abi } from "viem";
|
|
20
|
-
async function getUSDCBalance({
|
|
21
|
-
address,
|
|
22
|
-
network = DEFAULT_NETWORK
|
|
23
|
-
}) {
|
|
24
|
-
const caip2 = toCaip2(network);
|
|
25
|
-
const chain = getChain(caip2);
|
|
26
|
-
if (!chain) throw new Error(`Unsupported network: ${network}`);
|
|
27
|
-
const usdcAddress = getUSDCAddress(caip2);
|
|
28
|
-
if (!usdcAddress) throw new Error(`No USDC address for network: ${network}`);
|
|
29
|
-
log.debug(`Reading USDC balance for ${address} on ${chain.name}`);
|
|
30
|
-
const client = createPublicClient({ chain, transport: http() });
|
|
31
|
-
const balance = await client.readContract({
|
|
32
|
-
address: usdcAddress,
|
|
33
|
-
abi: erc20Abi,
|
|
34
|
-
functionName: "balanceOf",
|
|
35
|
-
args: [address]
|
|
36
|
-
});
|
|
37
|
-
return tokenBigIntToNumber(balance);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export {
|
|
41
|
-
tokenStringToNumber,
|
|
42
|
-
getUSDCBalance
|
|
43
|
-
};
|
package/dist/fund-743A34XB.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
getWallet,
|
|
3
|
-
promptDeposit
|
|
4
|
-
} from "./chunk-FFXFOKKF.js";
|
|
5
|
-
|
|
6
|
-
// src/fund/index.ts
|
|
7
|
-
import { intro, outro } from "@clack/prompts";
|
|
8
|
-
import chalk from "chalk";
|
|
9
|
-
var fundMcpServer = async (flags) => {
|
|
10
|
-
intro(chalk.bold(`Fund ${chalk.hex("#2563eb")("x402scan MCP")}`));
|
|
11
|
-
const {
|
|
12
|
-
account: { address }
|
|
13
|
-
} = await getWallet();
|
|
14
|
-
await promptDeposit(address, flags);
|
|
15
|
-
outro(chalk.bold.green("Your x402scan MCP server is funded!"));
|
|
16
|
-
};
|
|
17
|
-
export {
|
|
18
|
-
fundMcpServer
|
|
19
|
-
};
|