@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.
@@ -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
- };
@@ -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
- };
@@ -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
- };