moltspay 0.8.0 → 0.8.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/.env.example +10 -0
- package/dist/cli/index.js +207 -98
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +226 -111
- package/dist/cli/index.mjs.map +1 -1
- package/dist/index.js +321 -211
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +338 -228
- package/dist/index.mjs.map +1 -1
- package/dist/server/index.d.mts +23 -11
- package/dist/server/index.d.ts +23 -11
- package/dist/server/index.js +213 -153
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +211 -154
- package/dist/server/index.mjs.map +1 -1
- package/package.json +3 -1
package/dist/index.js
CHANGED
|
@@ -2905,7 +2905,7 @@ function alphabet(letters) {
|
|
|
2905
2905
|
};
|
|
2906
2906
|
}
|
|
2907
2907
|
// @__NO_SIDE_EFFECTS__
|
|
2908
|
-
function
|
|
2908
|
+
function join4(separator = "") {
|
|
2909
2909
|
astr("join", separator);
|
|
2910
2910
|
return {
|
|
2911
2911
|
encode: (from) => {
|
|
@@ -3112,10 +3112,10 @@ var init_esm = __esm({
|
|
|
3112
3112
|
convertRadix2,
|
|
3113
3113
|
radix,
|
|
3114
3114
|
radix2,
|
|
3115
|
-
join:
|
|
3115
|
+
join: join4,
|
|
3116
3116
|
padding
|
|
3117
3117
|
};
|
|
3118
|
-
genBase58 = /* @__NO_SIDE_EFFECTS__ */ (abc) => /* @__PURE__ */ chain(/* @__PURE__ */ radix(58), /* @__PURE__ */ alphabet(abc), /* @__PURE__ */
|
|
3118
|
+
genBase58 = /* @__NO_SIDE_EFFECTS__ */ (abc) => /* @__PURE__ */ chain(/* @__PURE__ */ radix(58), /* @__PURE__ */ alphabet(abc), /* @__PURE__ */ join4(""));
|
|
3119
3119
|
base58 = /* @__PURE__ */ genBase58("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz");
|
|
3120
3120
|
createBase58check = (sha2566) => /* @__PURE__ */ chain(checksum(4, (data) => sha2566(sha2566(data))), base58);
|
|
3121
3121
|
}
|
|
@@ -3263,14 +3263,14 @@ var init_esm2 = __esm({
|
|
|
3263
3263
|
}
|
|
3264
3264
|
this.pubHash = hash160(this.pubKey);
|
|
3265
3265
|
}
|
|
3266
|
-
derive(
|
|
3267
|
-
if (!/^[mM]'?/.test(
|
|
3266
|
+
derive(path3) {
|
|
3267
|
+
if (!/^[mM]'?/.test(path3)) {
|
|
3268
3268
|
throw new Error('Path must start with "m" or "M"');
|
|
3269
3269
|
}
|
|
3270
|
-
if (/^[mM]'?$/.test(
|
|
3270
|
+
if (/^[mM]'?$/.test(path3)) {
|
|
3271
3271
|
return this;
|
|
3272
3272
|
}
|
|
3273
|
-
const parts =
|
|
3273
|
+
const parts = path3.replace(/^[mM]'?\//, "").split("/");
|
|
3274
3274
|
let child = this;
|
|
3275
3275
|
for (const c of parts) {
|
|
3276
3276
|
const m = /^(\d+)('?)$/.exec(c);
|
|
@@ -9631,8 +9631,8 @@ var init_privateKeyToAccount = __esm({
|
|
|
9631
9631
|
});
|
|
9632
9632
|
|
|
9633
9633
|
// node_modules/viem/_esm/accounts/hdKeyToAccount.js
|
|
9634
|
-
function hdKeyToAccount(hdKey_, { accountIndex = 0, addressIndex = 0, changeIndex = 0, path:
|
|
9635
|
-
const hdKey = hdKey_.derive(
|
|
9634
|
+
function hdKeyToAccount(hdKey_, { accountIndex = 0, addressIndex = 0, changeIndex = 0, path: path3, ...options } = {}) {
|
|
9635
|
+
const hdKey = hdKey_.derive(path3 || `m/44'/60'/${accountIndex}'/${changeIndex}/${addressIndex}`);
|
|
9636
9636
|
const account = privateKeyToAccount(toHex(hdKey.privateKey), options);
|
|
9637
9637
|
return {
|
|
9638
9638
|
...account,
|
|
@@ -30369,85 +30369,7 @@ init_cjs_shims();
|
|
|
30369
30369
|
init_cjs_shims();
|
|
30370
30370
|
var import_fs = require("fs");
|
|
30371
30371
|
var import_http = require("http");
|
|
30372
|
-
var
|
|
30373
|
-
|
|
30374
|
-
// src/chains/index.ts
|
|
30375
|
-
init_cjs_shims();
|
|
30376
|
-
var CHAINS = {
|
|
30377
|
-
// ============ Mainnet ============
|
|
30378
|
-
base: {
|
|
30379
|
-
name: "Base",
|
|
30380
|
-
chainId: 8453,
|
|
30381
|
-
rpc: "https://mainnet.base.org",
|
|
30382
|
-
usdc: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
30383
|
-
explorer: "https://basescan.org/address/",
|
|
30384
|
-
explorerTx: "https://basescan.org/tx/",
|
|
30385
|
-
avgBlockTime: 2
|
|
30386
|
-
},
|
|
30387
|
-
polygon: {
|
|
30388
|
-
name: "Polygon",
|
|
30389
|
-
chainId: 137,
|
|
30390
|
-
rpc: "https://polygon-rpc.com",
|
|
30391
|
-
usdc: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
|
|
30392
|
-
explorer: "https://polygonscan.com/address/",
|
|
30393
|
-
explorerTx: "https://polygonscan.com/tx/",
|
|
30394
|
-
avgBlockTime: 2
|
|
30395
|
-
},
|
|
30396
|
-
ethereum: {
|
|
30397
|
-
name: "Ethereum",
|
|
30398
|
-
chainId: 1,
|
|
30399
|
-
rpc: "https://eth.llamarpc.com",
|
|
30400
|
-
usdc: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
30401
|
-
explorer: "https://etherscan.io/address/",
|
|
30402
|
-
explorerTx: "https://etherscan.io/tx/",
|
|
30403
|
-
avgBlockTime: 12
|
|
30404
|
-
},
|
|
30405
|
-
// ============ Testnet ============
|
|
30406
|
-
base_sepolia: {
|
|
30407
|
-
name: "Base Sepolia",
|
|
30408
|
-
chainId: 84532,
|
|
30409
|
-
rpc: "https://sepolia.base.org",
|
|
30410
|
-
usdc: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
|
|
30411
|
-
explorer: "https://sepolia.basescan.org/address/",
|
|
30412
|
-
explorerTx: "https://sepolia.basescan.org/tx/",
|
|
30413
|
-
avgBlockTime: 2
|
|
30414
|
-
},
|
|
30415
|
-
sepolia: {
|
|
30416
|
-
name: "Sepolia",
|
|
30417
|
-
chainId: 11155111,
|
|
30418
|
-
rpc: "https://rpc.sepolia.org",
|
|
30419
|
-
usdc: "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238",
|
|
30420
|
-
explorer: "https://sepolia.etherscan.io/address/",
|
|
30421
|
-
explorerTx: "https://sepolia.etherscan.io/tx/",
|
|
30422
|
-
avgBlockTime: 12
|
|
30423
|
-
}
|
|
30424
|
-
};
|
|
30425
|
-
function getChain(name) {
|
|
30426
|
-
const config = CHAINS[name];
|
|
30427
|
-
if (!config) {
|
|
30428
|
-
throw new Error(`Unsupported chain: ${name}. Supported: ${Object.keys(CHAINS).join(", ")}`);
|
|
30429
|
-
}
|
|
30430
|
-
return config;
|
|
30431
|
-
}
|
|
30432
|
-
function listChains() {
|
|
30433
|
-
return Object.keys(CHAINS);
|
|
30434
|
-
}
|
|
30435
|
-
function getChainById(chainId) {
|
|
30436
|
-
return Object.values(CHAINS).find((c) => c.chainId === chainId);
|
|
30437
|
-
}
|
|
30438
|
-
var ERC20_ABI = [
|
|
30439
|
-
"function balanceOf(address owner) view returns (uint256)",
|
|
30440
|
-
"function transfer(address to, uint256 amount) returns (bool)",
|
|
30441
|
-
"function approve(address spender, uint256 amount) returns (bool)",
|
|
30442
|
-
"function allowance(address owner, address spender) view returns (uint256)",
|
|
30443
|
-
"function decimals() view returns (uint8)",
|
|
30444
|
-
"function symbol() view returns (string)",
|
|
30445
|
-
"function name() view returns (string)",
|
|
30446
|
-
"function nonces(address owner) view returns (uint256)",
|
|
30447
|
-
"function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)",
|
|
30448
|
-
"event Transfer(address indexed from, address indexed to, uint256 value)",
|
|
30449
|
-
"event Approval(address indexed owner, address indexed spender, uint256 value)"
|
|
30450
|
-
];
|
|
30372
|
+
var path = __toESM(require("path"));
|
|
30451
30373
|
|
|
30452
30374
|
// src/server/types.ts
|
|
30453
30375
|
init_cjs_shims();
|
|
@@ -30456,34 +30378,92 @@ init_cjs_shims();
|
|
|
30456
30378
|
var X402_VERSION = 2;
|
|
30457
30379
|
var PAYMENT_REQUIRED_HEADER = "x-payment-required";
|
|
30458
30380
|
var PAYMENT_HEADER = "x-payment";
|
|
30381
|
+
var PAYMENT_RESPONSE_HEADER = "x-payment-response";
|
|
30382
|
+
var FACILITATOR_TESTNET = "https://www.x402.org/facilitator";
|
|
30383
|
+
var FACILITATOR_MAINNET = "https://api.cdp.coinbase.com/platform/v2/x402";
|
|
30384
|
+
function loadEnvFiles() {
|
|
30385
|
+
try {
|
|
30386
|
+
const dotenv = require("dotenv");
|
|
30387
|
+
const envPaths = [
|
|
30388
|
+
path.join(process.cwd(), ".env"),
|
|
30389
|
+
path.join(process.env.HOME || "", ".moltspay", ".env")
|
|
30390
|
+
];
|
|
30391
|
+
for (const envPath of envPaths) {
|
|
30392
|
+
if ((0, import_fs.existsSync)(envPath)) {
|
|
30393
|
+
dotenv.config({ path: envPath });
|
|
30394
|
+
console.log(`[MoltsPay] Loaded config from ${envPath}`);
|
|
30395
|
+
break;
|
|
30396
|
+
}
|
|
30397
|
+
}
|
|
30398
|
+
} catch {
|
|
30399
|
+
}
|
|
30400
|
+
}
|
|
30401
|
+
function getCDPConfig() {
|
|
30402
|
+
loadEnvFiles();
|
|
30403
|
+
return {
|
|
30404
|
+
useMainnet: process.env.USE_MAINNET?.toLowerCase() === "true",
|
|
30405
|
+
apiKeyId: process.env.CDP_API_KEY_ID,
|
|
30406
|
+
apiKeySecret: process.env.CDP_API_KEY_SECRET
|
|
30407
|
+
};
|
|
30408
|
+
}
|
|
30409
|
+
async function getCDPAuthHeaders(method, urlPath, body) {
|
|
30410
|
+
const config = getCDPConfig();
|
|
30411
|
+
if (!config.apiKeyId || !config.apiKeySecret) {
|
|
30412
|
+
throw new Error("CDP_API_KEY_ID and CDP_API_KEY_SECRET required for mainnet");
|
|
30413
|
+
}
|
|
30414
|
+
try {
|
|
30415
|
+
const { getAuthHeaders } = await import("@coinbase/cdp-sdk/auth");
|
|
30416
|
+
const headers = await getAuthHeaders({
|
|
30417
|
+
apiKeyId: config.apiKeyId,
|
|
30418
|
+
apiKeySecret: config.apiKeySecret,
|
|
30419
|
+
requestMethod: method,
|
|
30420
|
+
requestHost: "api.cdp.coinbase.com",
|
|
30421
|
+
requestPath: urlPath,
|
|
30422
|
+
requestBody: body
|
|
30423
|
+
});
|
|
30424
|
+
return headers;
|
|
30425
|
+
} catch (err) {
|
|
30426
|
+
console.error("[MoltsPay] Failed to generate CDP auth headers:", err.message);
|
|
30427
|
+
throw err;
|
|
30428
|
+
}
|
|
30429
|
+
}
|
|
30459
30430
|
var MoltsPayServer = class {
|
|
30460
30431
|
manifest;
|
|
30461
30432
|
skills = /* @__PURE__ */ new Map();
|
|
30462
30433
|
options;
|
|
30463
|
-
|
|
30464
|
-
|
|
30434
|
+
cdpConfig;
|
|
30435
|
+
facilitatorUrl;
|
|
30436
|
+
networkId;
|
|
30465
30437
|
constructor(servicesPath, options = {}) {
|
|
30438
|
+
this.cdpConfig = getCDPConfig();
|
|
30466
30439
|
const content = (0, import_fs.readFileSync)(servicesPath, "utf-8");
|
|
30467
30440
|
this.manifest = JSON.parse(content);
|
|
30468
30441
|
this.options = {
|
|
30469
30442
|
port: options.port || 3e3,
|
|
30470
|
-
host: options.host || "0.0.0.0"
|
|
30471
|
-
privateKey: options.privateKey || process.env.MOLTSPAY_PRIVATE_KEY
|
|
30443
|
+
host: options.host || "0.0.0.0"
|
|
30472
30444
|
};
|
|
30473
|
-
if (this.
|
|
30474
|
-
|
|
30475
|
-
|
|
30476
|
-
|
|
30477
|
-
this.wallet = new import_ethers.ethers.Wallet(this.options.privateKey, this.provider);
|
|
30478
|
-
console.log(`[MoltsPay] Payment wallet: ${this.wallet.address}`);
|
|
30479
|
-
} catch (err) {
|
|
30480
|
-
console.warn("[MoltsPay] Warning: Could not initialize wallet for payment claims");
|
|
30445
|
+
if (this.cdpConfig.useMainnet) {
|
|
30446
|
+
if (!this.cdpConfig.apiKeyId || !this.cdpConfig.apiKeySecret) {
|
|
30447
|
+
console.warn("[MoltsPay] WARNING: USE_MAINNET=true but CDP keys not set!");
|
|
30448
|
+
console.warn("[MoltsPay] Set CDP_API_KEY_ID and CDP_API_KEY_SECRET in ~/.moltspay/.env");
|
|
30481
30449
|
}
|
|
30450
|
+
this.facilitatorUrl = FACILITATOR_MAINNET;
|
|
30451
|
+
this.networkId = "eip155:8453";
|
|
30452
|
+
} else {
|
|
30453
|
+
this.facilitatorUrl = options.facilitatorUrl || FACILITATOR_TESTNET;
|
|
30454
|
+
this.networkId = "eip155:84532";
|
|
30482
30455
|
}
|
|
30456
|
+
const networkName = this.cdpConfig.useMainnet ? "Base mainnet" : "Base Sepolia (testnet)";
|
|
30457
|
+
const facilitatorName = this.cdpConfig.useMainnet ? "CDP" : "x402.org";
|
|
30483
30458
|
console.log(`[MoltsPay] Loaded ${this.manifest.services.length} services from ${servicesPath}`);
|
|
30484
30459
|
console.log(`[MoltsPay] Provider: ${this.manifest.provider.name}`);
|
|
30485
30460
|
console.log(`[MoltsPay] Receive wallet: ${this.manifest.provider.wallet}`);
|
|
30486
|
-
console.log(`[MoltsPay]
|
|
30461
|
+
console.log(`[MoltsPay] Network: ${this.networkId} (${networkName})`);
|
|
30462
|
+
console.log(`[MoltsPay] Facilitator: ${facilitatorName} (${this.facilitatorUrl})`);
|
|
30463
|
+
if (this.cdpConfig.useMainnet && this.cdpConfig.apiKeyId) {
|
|
30464
|
+
console.log(`[MoltsPay] CDP API Key: ${this.cdpConfig.apiKeyId.slice(0, 8)}...`);
|
|
30465
|
+
}
|
|
30466
|
+
console.log(`[MoltsPay] Protocol: x402 (gasless for both client AND server)`);
|
|
30487
30467
|
}
|
|
30488
30468
|
/**
|
|
30489
30469
|
* Register a skill handler for a service
|
|
@@ -30493,48 +30473,45 @@ var MoltsPayServer = class {
|
|
|
30493
30473
|
if (!config) {
|
|
30494
30474
|
throw new Error(`Service '${serviceId}' not found in manifest`);
|
|
30495
30475
|
}
|
|
30496
|
-
this.skills.set(serviceId, {
|
|
30497
|
-
id: serviceId,
|
|
30498
|
-
config,
|
|
30499
|
-
handler
|
|
30500
|
-
});
|
|
30501
|
-
console.log(`[MoltsPay] Registered skill: ${serviceId} ($${config.price} ${config.currency})`);
|
|
30476
|
+
this.skills.set(serviceId, { id: serviceId, config, handler });
|
|
30502
30477
|
return this;
|
|
30503
30478
|
}
|
|
30504
30479
|
/**
|
|
30505
|
-
* Start
|
|
30480
|
+
* Start HTTP server
|
|
30506
30481
|
*/
|
|
30507
30482
|
listen(port) {
|
|
30508
|
-
const p = port || this.options.port;
|
|
30483
|
+
const p = port || this.options.port || 3e3;
|
|
30484
|
+
const host = this.options.host || "0.0.0.0";
|
|
30509
30485
|
const server = (0, import_http.createServer)((req, res) => this.handleRequest(req, res));
|
|
30510
|
-
server.listen(p,
|
|
30511
|
-
console.log(`[MoltsPay] Server listening on http://${
|
|
30486
|
+
server.listen(p, host, () => {
|
|
30487
|
+
console.log(`[MoltsPay] Server listening on http://${host}:${p}`);
|
|
30512
30488
|
console.log(`[MoltsPay] Endpoints:`);
|
|
30513
30489
|
console.log(` GET /services - List available services`);
|
|
30514
30490
|
console.log(` POST /execute - Execute service (x402 payment)`);
|
|
30515
30491
|
});
|
|
30516
30492
|
}
|
|
30493
|
+
/**
|
|
30494
|
+
* Handle incoming request
|
|
30495
|
+
*/
|
|
30517
30496
|
async handleRequest(req, res) {
|
|
30518
|
-
const url = new URL(req.url || "/", `http://${req.headers.host}`);
|
|
30519
|
-
const path2 = url.pathname;
|
|
30520
|
-
const method = req.method || "GET";
|
|
30521
30497
|
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
30522
30498
|
res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
|
30523
30499
|
res.setHeader("Access-Control-Allow-Headers", "Content-Type, X-Payment");
|
|
30524
30500
|
res.setHeader("Access-Control-Expose-Headers", "X-Payment-Required, X-Payment-Response");
|
|
30525
|
-
if (method === "OPTIONS") {
|
|
30501
|
+
if (req.method === "OPTIONS") {
|
|
30526
30502
|
res.writeHead(204);
|
|
30527
30503
|
res.end();
|
|
30528
30504
|
return;
|
|
30529
30505
|
}
|
|
30530
30506
|
try {
|
|
30531
|
-
|
|
30507
|
+
const url = new URL(req.url || "/", `http://${req.headers.host}`);
|
|
30508
|
+
if (url.pathname === "/services" && req.method === "GET") {
|
|
30532
30509
|
return this.handleGetServices(res);
|
|
30533
30510
|
}
|
|
30534
|
-
if (
|
|
30511
|
+
if (url.pathname === "/execute" && req.method === "POST") {
|
|
30535
30512
|
const body = await this.readBody(req);
|
|
30536
30513
|
const paymentHeader = req.headers[PAYMENT_HEADER];
|
|
30537
|
-
return this.handleExecute(body, paymentHeader, res);
|
|
30514
|
+
return await this.handleExecute(body, paymentHeader, res);
|
|
30538
30515
|
}
|
|
30539
30516
|
this.sendJson(res, 404, { error: "Not found" });
|
|
30540
30517
|
} catch (err) {
|
|
@@ -30546,7 +30523,6 @@ var MoltsPayServer = class {
|
|
|
30546
30523
|
* GET /services - List available services
|
|
30547
30524
|
*/
|
|
30548
30525
|
handleGetServices(res) {
|
|
30549
|
-
const chain2 = getChain(this.manifest.provider.chain);
|
|
30550
30526
|
const services = this.manifest.services.map((s) => ({
|
|
30551
30527
|
id: s.id,
|
|
30552
30528
|
name: s.name,
|
|
@@ -30562,15 +30538,15 @@ var MoltsPayServer = class {
|
|
|
30562
30538
|
services,
|
|
30563
30539
|
x402: {
|
|
30564
30540
|
version: X402_VERSION,
|
|
30565
|
-
network:
|
|
30566
|
-
schemes: ["exact"]
|
|
30541
|
+
network: this.networkId,
|
|
30542
|
+
schemes: ["exact"],
|
|
30543
|
+
facilitator: this.cdpConfig.useMainnet ? "cdp" : "x402.org",
|
|
30544
|
+
mainnet: this.cdpConfig.useMainnet
|
|
30567
30545
|
}
|
|
30568
30546
|
});
|
|
30569
30547
|
}
|
|
30570
30548
|
/**
|
|
30571
30549
|
* POST /execute - Execute service with x402 payment
|
|
30572
|
-
* Body: { service: string, params: object }
|
|
30573
|
-
* Header: X-Payment (optional - if missing, returns 402)
|
|
30574
30550
|
*/
|
|
30575
30551
|
async handleExecute(body, paymentHeader, res) {
|
|
30576
30552
|
const { service, params } = body;
|
|
@@ -30600,6 +30576,11 @@ var MoltsPayServer = class {
|
|
|
30600
30576
|
if (!validation.valid) {
|
|
30601
30577
|
return this.sendJson(res, 402, { error: validation.error });
|
|
30602
30578
|
}
|
|
30579
|
+
console.log(`[MoltsPay] Verifying payment with facilitator...`);
|
|
30580
|
+
const verifyResult = await this.verifyWithFacilitator(payment, skill.config);
|
|
30581
|
+
if (!verifyResult.valid) {
|
|
30582
|
+
return this.sendJson(res, 402, { error: `Payment verification failed: ${verifyResult.error}` });
|
|
30583
|
+
}
|
|
30603
30584
|
console.log(`[MoltsPay] Executing skill: ${service}`);
|
|
30604
30585
|
let result;
|
|
30605
30586
|
try {
|
|
@@ -30611,32 +30592,46 @@ var MoltsPayServer = class {
|
|
|
30611
30592
|
message: err.message
|
|
30612
30593
|
});
|
|
30613
30594
|
}
|
|
30614
|
-
console.log(`[MoltsPay] Skill succeeded,
|
|
30615
|
-
let
|
|
30595
|
+
console.log(`[MoltsPay] Skill succeeded, settling payment...`);
|
|
30596
|
+
let settlement = null;
|
|
30616
30597
|
try {
|
|
30617
|
-
|
|
30618
|
-
console.log(`[MoltsPay] Payment
|
|
30598
|
+
settlement = await this.settleWithFacilitator(payment, skill.config);
|
|
30599
|
+
console.log(`[MoltsPay] Payment settled: ${settlement.transaction || "pending"}`);
|
|
30619
30600
|
} catch (err) {
|
|
30620
|
-
console.error("[MoltsPay]
|
|
30601
|
+
console.error("[MoltsPay] Settlement failed:", err.message);
|
|
30602
|
+
}
|
|
30603
|
+
const responseHeaders = {};
|
|
30604
|
+
if (settlement) {
|
|
30605
|
+
const responsePayload = {
|
|
30606
|
+
success: true,
|
|
30607
|
+
transaction: settlement.transaction,
|
|
30608
|
+
network: payment.network
|
|
30609
|
+
};
|
|
30610
|
+
responseHeaders[PAYMENT_RESPONSE_HEADER] = Buffer.from(
|
|
30611
|
+
JSON.stringify(responsePayload)
|
|
30612
|
+
).toString("base64");
|
|
30621
30613
|
}
|
|
30622
30614
|
this.sendJson(res, 200, {
|
|
30623
30615
|
success: true,
|
|
30624
30616
|
result,
|
|
30625
|
-
payment:
|
|
30626
|
-
});
|
|
30617
|
+
payment: settlement ? { transaction: settlement.transaction, status: "settled" } : { status: "pending" }
|
|
30618
|
+
}, responseHeaders);
|
|
30627
30619
|
}
|
|
30628
30620
|
/**
|
|
30629
30621
|
* Return 402 with x402 payment requirements
|
|
30630
30622
|
*/
|
|
30631
30623
|
sendPaymentRequired(config, res) {
|
|
30632
|
-
const chain2 = getChain(this.manifest.provider.chain);
|
|
30633
30624
|
const amountInUnits = Math.floor(config.price * 1e6).toString();
|
|
30634
30625
|
const requirements = [{
|
|
30635
30626
|
scheme: "exact",
|
|
30636
|
-
network:
|
|
30627
|
+
network: this.networkId,
|
|
30637
30628
|
maxAmountRequired: amountInUnits,
|
|
30638
30629
|
resource: this.manifest.provider.wallet,
|
|
30639
|
-
description: `${config.name} - $${config.price} ${config.currency}
|
|
30630
|
+
description: `${config.name} - $${config.price} ${config.currency}`,
|
|
30631
|
+
extra: JSON.stringify({
|
|
30632
|
+
facilitator: this.cdpConfig.useMainnet ? "cdp" : "x402.org",
|
|
30633
|
+
mainnet: this.cdpConfig.useMainnet
|
|
30634
|
+
})
|
|
30640
30635
|
}];
|
|
30641
30636
|
const encoded = Buffer.from(JSON.stringify(requirements)).toString("base64");
|
|
30642
30637
|
res.writeHead(402, {
|
|
@@ -30650,7 +30645,7 @@ var MoltsPayServer = class {
|
|
|
30650
30645
|
}, null, 2));
|
|
30651
30646
|
}
|
|
30652
30647
|
/**
|
|
30653
|
-
*
|
|
30648
|
+
* Basic payment validation
|
|
30654
30649
|
*/
|
|
30655
30650
|
validatePayment(payment, config) {
|
|
30656
30651
|
if (payment.x402Version !== X402_VERSION) {
|
|
@@ -30659,56 +30654,89 @@ var MoltsPayServer = class {
|
|
|
30659
30654
|
if (payment.scheme !== "exact") {
|
|
30660
30655
|
return { valid: false, error: `Unsupported scheme: ${payment.scheme}` };
|
|
30661
30656
|
}
|
|
30662
|
-
|
|
30663
|
-
|
|
30664
|
-
if (payment.network !== expectedNetwork) {
|
|
30665
|
-
return { valid: false, error: `Network mismatch: expected ${expectedNetwork}` };
|
|
30666
|
-
}
|
|
30667
|
-
const auth = payment.payload.authorization;
|
|
30668
|
-
if (auth.to.toLowerCase() !== this.manifest.provider.wallet.toLowerCase()) {
|
|
30669
|
-
return { valid: false, error: "Payment recipient mismatch" };
|
|
30670
|
-
}
|
|
30671
|
-
const amount = Number(auth.value) / 1e6;
|
|
30672
|
-
if (amount < config.price) {
|
|
30673
|
-
return { valid: false, error: `Insufficient amount: $${amount} < $${config.price}` };
|
|
30674
|
-
}
|
|
30675
|
-
const now = Math.floor(Date.now() / 1e3);
|
|
30676
|
-
if (Number(auth.validBefore) < now) {
|
|
30677
|
-
return { valid: false, error: "Payment authorization expired" };
|
|
30678
|
-
}
|
|
30679
|
-
if (Number(auth.validAfter) > now) {
|
|
30680
|
-
return { valid: false, error: "Payment authorization not yet valid" };
|
|
30657
|
+
if (payment.network !== this.networkId) {
|
|
30658
|
+
return { valid: false, error: `Network mismatch: expected ${this.networkId}, got ${payment.network}` };
|
|
30681
30659
|
}
|
|
30682
30660
|
return { valid: true };
|
|
30683
30661
|
}
|
|
30684
30662
|
/**
|
|
30685
|
-
*
|
|
30663
|
+
* Verify payment with facilitator (testnet or CDP)
|
|
30686
30664
|
*/
|
|
30687
|
-
async
|
|
30688
|
-
|
|
30689
|
-
|
|
30665
|
+
async verifyWithFacilitator(payment, config) {
|
|
30666
|
+
try {
|
|
30667
|
+
const amountInUnits = Math.floor(config.price * 1e6).toString();
|
|
30668
|
+
const requirements = {
|
|
30669
|
+
scheme: "exact",
|
|
30670
|
+
network: this.networkId,
|
|
30671
|
+
maxAmountRequired: amountInUnits,
|
|
30672
|
+
resource: this.manifest.provider.wallet,
|
|
30673
|
+
payTo: this.manifest.provider.wallet
|
|
30674
|
+
};
|
|
30675
|
+
const requestBody = {
|
|
30676
|
+
paymentPayload: payment,
|
|
30677
|
+
paymentRequirements: requirements
|
|
30678
|
+
};
|
|
30679
|
+
let headers = { "Content-Type": "application/json" };
|
|
30680
|
+
if (this.cdpConfig.useMainnet) {
|
|
30681
|
+
const authHeaders = await getCDPAuthHeaders(
|
|
30682
|
+
"POST",
|
|
30683
|
+
"/platform/v2/x402/verify",
|
|
30684
|
+
requestBody
|
|
30685
|
+
);
|
|
30686
|
+
headers = { ...headers, ...authHeaders };
|
|
30687
|
+
}
|
|
30688
|
+
const response = await fetch(`${this.facilitatorUrl}/verify`, {
|
|
30689
|
+
method: "POST",
|
|
30690
|
+
headers,
|
|
30691
|
+
body: JSON.stringify(requestBody)
|
|
30692
|
+
});
|
|
30693
|
+
const result = await response.json();
|
|
30694
|
+
if (!response.ok || !result.isValid) {
|
|
30695
|
+
return { valid: false, error: result.invalidReason || result.error || "Verification failed" };
|
|
30696
|
+
}
|
|
30697
|
+
return { valid: true };
|
|
30698
|
+
} catch (err) {
|
|
30699
|
+
return { valid: false, error: `Facilitator error: ${err.message}` };
|
|
30690
30700
|
}
|
|
30691
|
-
|
|
30692
|
-
|
|
30693
|
-
|
|
30694
|
-
|
|
30695
|
-
|
|
30696
|
-
|
|
30697
|
-
|
|
30698
|
-
|
|
30699
|
-
|
|
30700
|
-
|
|
30701
|
-
|
|
30702
|
-
|
|
30703
|
-
|
|
30704
|
-
|
|
30705
|
-
|
|
30706
|
-
|
|
30707
|
-
|
|
30708
|
-
|
|
30709
|
-
)
|
|
30710
|
-
|
|
30711
|
-
|
|
30701
|
+
}
|
|
30702
|
+
/**
|
|
30703
|
+
* Settle payment with facilitator (execute on-chain transfer)
|
|
30704
|
+
*/
|
|
30705
|
+
async settleWithFacilitator(payment, config) {
|
|
30706
|
+
const amountInUnits = Math.floor(config.price * 1e6).toString();
|
|
30707
|
+
const requirements = {
|
|
30708
|
+
scheme: "exact",
|
|
30709
|
+
network: this.networkId,
|
|
30710
|
+
maxAmountRequired: amountInUnits,
|
|
30711
|
+
resource: this.manifest.provider.wallet,
|
|
30712
|
+
payTo: this.manifest.provider.wallet
|
|
30713
|
+
};
|
|
30714
|
+
const requestBody = {
|
|
30715
|
+
paymentPayload: payment,
|
|
30716
|
+
paymentRequirements: requirements
|
|
30717
|
+
};
|
|
30718
|
+
let headers = { "Content-Type": "application/json" };
|
|
30719
|
+
if (this.cdpConfig.useMainnet) {
|
|
30720
|
+
const authHeaders = await getCDPAuthHeaders(
|
|
30721
|
+
"POST",
|
|
30722
|
+
"/platform/v2/x402/settle",
|
|
30723
|
+
requestBody
|
|
30724
|
+
);
|
|
30725
|
+
headers = { ...headers, ...authHeaders };
|
|
30726
|
+
}
|
|
30727
|
+
const response = await fetch(`${this.facilitatorUrl}/settle`, {
|
|
30728
|
+
method: "POST",
|
|
30729
|
+
headers,
|
|
30730
|
+
body: JSON.stringify(requestBody)
|
|
30731
|
+
});
|
|
30732
|
+
const result = await response.json();
|
|
30733
|
+
if (!response.ok || !result.success) {
|
|
30734
|
+
throw new Error(result.error || result.errorReason || "Settlement failed");
|
|
30735
|
+
}
|
|
30736
|
+
return {
|
|
30737
|
+
transaction: result.transaction,
|
|
30738
|
+
status: result.status || "settled"
|
|
30739
|
+
};
|
|
30712
30740
|
}
|
|
30713
30741
|
async readBody(req) {
|
|
30714
30742
|
return new Promise((resolve, reject) => {
|
|
@@ -30724,8 +30752,12 @@ var MoltsPayServer = class {
|
|
|
30724
30752
|
req.on("error", reject);
|
|
30725
30753
|
});
|
|
30726
30754
|
}
|
|
30727
|
-
sendJson(res, status, data) {
|
|
30728
|
-
|
|
30755
|
+
sendJson(res, status, data, extraHeaders) {
|
|
30756
|
+
const headers = { "Content-Type": "application/json" };
|
|
30757
|
+
if (extraHeaders) {
|
|
30758
|
+
Object.assign(headers, extraHeaders);
|
|
30759
|
+
}
|
|
30760
|
+
res.writeHead(status, headers);
|
|
30729
30761
|
res.end(JSON.stringify(data, null, 2));
|
|
30730
30762
|
}
|
|
30731
30763
|
};
|
|
@@ -30735,7 +30767,85 @@ init_cjs_shims();
|
|
|
30735
30767
|
var import_fs2 = require("fs");
|
|
30736
30768
|
var import_os = require("os");
|
|
30737
30769
|
var import_path = require("path");
|
|
30738
|
-
var
|
|
30770
|
+
var import_ethers = require("ethers");
|
|
30771
|
+
|
|
30772
|
+
// src/chains/index.ts
|
|
30773
|
+
init_cjs_shims();
|
|
30774
|
+
var CHAINS = {
|
|
30775
|
+
// ============ Mainnet ============
|
|
30776
|
+
base: {
|
|
30777
|
+
name: "Base",
|
|
30778
|
+
chainId: 8453,
|
|
30779
|
+
rpc: "https://mainnet.base.org",
|
|
30780
|
+
usdc: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
30781
|
+
explorer: "https://basescan.org/address/",
|
|
30782
|
+
explorerTx: "https://basescan.org/tx/",
|
|
30783
|
+
avgBlockTime: 2
|
|
30784
|
+
},
|
|
30785
|
+
polygon: {
|
|
30786
|
+
name: "Polygon",
|
|
30787
|
+
chainId: 137,
|
|
30788
|
+
rpc: "https://polygon-rpc.com",
|
|
30789
|
+
usdc: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
|
|
30790
|
+
explorer: "https://polygonscan.com/address/",
|
|
30791
|
+
explorerTx: "https://polygonscan.com/tx/",
|
|
30792
|
+
avgBlockTime: 2
|
|
30793
|
+
},
|
|
30794
|
+
ethereum: {
|
|
30795
|
+
name: "Ethereum",
|
|
30796
|
+
chainId: 1,
|
|
30797
|
+
rpc: "https://eth.llamarpc.com",
|
|
30798
|
+
usdc: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
30799
|
+
explorer: "https://etherscan.io/address/",
|
|
30800
|
+
explorerTx: "https://etherscan.io/tx/",
|
|
30801
|
+
avgBlockTime: 12
|
|
30802
|
+
},
|
|
30803
|
+
// ============ Testnet ============
|
|
30804
|
+
base_sepolia: {
|
|
30805
|
+
name: "Base Sepolia",
|
|
30806
|
+
chainId: 84532,
|
|
30807
|
+
rpc: "https://sepolia.base.org",
|
|
30808
|
+
usdc: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
|
|
30809
|
+
explorer: "https://sepolia.basescan.org/address/",
|
|
30810
|
+
explorerTx: "https://sepolia.basescan.org/tx/",
|
|
30811
|
+
avgBlockTime: 2
|
|
30812
|
+
},
|
|
30813
|
+
sepolia: {
|
|
30814
|
+
name: "Sepolia",
|
|
30815
|
+
chainId: 11155111,
|
|
30816
|
+
rpc: "https://rpc.sepolia.org",
|
|
30817
|
+
usdc: "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238",
|
|
30818
|
+
explorer: "https://sepolia.etherscan.io/address/",
|
|
30819
|
+
explorerTx: "https://sepolia.etherscan.io/tx/",
|
|
30820
|
+
avgBlockTime: 12
|
|
30821
|
+
}
|
|
30822
|
+
};
|
|
30823
|
+
function getChain(name) {
|
|
30824
|
+
const config = CHAINS[name];
|
|
30825
|
+
if (!config) {
|
|
30826
|
+
throw new Error(`Unsupported chain: ${name}. Supported: ${Object.keys(CHAINS).join(", ")}`);
|
|
30827
|
+
}
|
|
30828
|
+
return config;
|
|
30829
|
+
}
|
|
30830
|
+
function listChains() {
|
|
30831
|
+
return Object.keys(CHAINS);
|
|
30832
|
+
}
|
|
30833
|
+
function getChainById(chainId) {
|
|
30834
|
+
return Object.values(CHAINS).find((c) => c.chainId === chainId);
|
|
30835
|
+
}
|
|
30836
|
+
var ERC20_ABI = [
|
|
30837
|
+
"function balanceOf(address owner) view returns (uint256)",
|
|
30838
|
+
"function transfer(address to, uint256 amount) returns (bool)",
|
|
30839
|
+
"function approve(address spender, uint256 amount) returns (bool)",
|
|
30840
|
+
"function allowance(address owner, address spender) view returns (uint256)",
|
|
30841
|
+
"function decimals() view returns (uint8)",
|
|
30842
|
+
"function symbol() view returns (string)",
|
|
30843
|
+
"function name() view returns (string)",
|
|
30844
|
+
"function nonces(address owner) view returns (uint256)",
|
|
30845
|
+
"function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)",
|
|
30846
|
+
"event Transfer(address indexed from, address indexed to, uint256 value)",
|
|
30847
|
+
"event Approval(address indexed owner, address indexed spender, uint256 value)"
|
|
30848
|
+
];
|
|
30739
30849
|
|
|
30740
30850
|
// src/client/types.ts
|
|
30741
30851
|
init_cjs_shims();
|
|
@@ -30763,7 +30873,7 @@ var MoltsPayClient = class {
|
|
|
30763
30873
|
this.config = this.loadConfig();
|
|
30764
30874
|
this.walletData = this.loadWallet();
|
|
30765
30875
|
if (this.walletData) {
|
|
30766
|
-
this.wallet = new
|
|
30876
|
+
this.wallet = new import_ethers.Wallet(this.walletData.privateKey);
|
|
30767
30877
|
}
|
|
30768
30878
|
}
|
|
30769
30879
|
/**
|
|
@@ -30884,7 +30994,7 @@ var MoltsPayClient = class {
|
|
|
30884
30994
|
async signEIP3009(to, amount, chain2) {
|
|
30885
30995
|
const validAfter = 0;
|
|
30886
30996
|
const validBefore = Math.floor(Date.now() / 1e3) + 3600;
|
|
30887
|
-
const nonce =
|
|
30997
|
+
const nonce = import_ethers.ethers.hexlify(import_ethers.ethers.randomBytes(32));
|
|
30888
30998
|
const value = BigInt(Math.floor(amount * 1e6)).toString();
|
|
30889
30999
|
const authorization = {
|
|
30890
31000
|
from: this.wallet.address,
|
|
@@ -30966,7 +31076,7 @@ var MoltsPayClient = class {
|
|
|
30966
31076
|
*/
|
|
30967
31077
|
static init(configDir, options) {
|
|
30968
31078
|
(0, import_fs2.mkdirSync)(configDir, { recursive: true });
|
|
30969
|
-
const wallet =
|
|
31079
|
+
const wallet = import_ethers.Wallet.createRandom();
|
|
30970
31080
|
const walletData = {
|
|
30971
31081
|
address: wallet.address,
|
|
30972
31082
|
privateKey: wallet.privateKey,
|
|
@@ -30998,14 +31108,14 @@ var MoltsPayClient = class {
|
|
|
30998
31108
|
} catch {
|
|
30999
31109
|
throw new Error(`Unknown chain: ${this.config.chain}`);
|
|
31000
31110
|
}
|
|
31001
|
-
const provider = new
|
|
31111
|
+
const provider = new import_ethers.ethers.JsonRpcProvider(chain2.rpc);
|
|
31002
31112
|
const nativeBalance = await provider.getBalance(this.wallet.address);
|
|
31003
31113
|
const usdcAbi = ["function balanceOf(address) view returns (uint256)"];
|
|
31004
|
-
const usdc = new
|
|
31114
|
+
const usdc = new import_ethers.ethers.Contract(chain2.usdc, usdcAbi, provider);
|
|
31005
31115
|
const usdcBalance = await usdc.balanceOf(this.wallet.address);
|
|
31006
31116
|
return {
|
|
31007
|
-
usdc: parseFloat(
|
|
31008
|
-
native: parseFloat(
|
|
31117
|
+
usdc: parseFloat(import_ethers.ethers.formatUnits(usdcBalance, 6)),
|
|
31118
|
+
native: parseFloat(import_ethers.ethers.formatEther(nativeBalance))
|
|
31009
31119
|
};
|
|
31010
31120
|
}
|
|
31011
31121
|
};
|
|
@@ -31015,11 +31125,11 @@ init_cjs_shims();
|
|
|
31015
31125
|
|
|
31016
31126
|
// src/wallet/Wallet.ts
|
|
31017
31127
|
init_cjs_shims();
|
|
31018
|
-
var
|
|
31128
|
+
var import_ethers2 = require("ethers");
|
|
31019
31129
|
|
|
31020
31130
|
// src/wallet/createWallet.ts
|
|
31021
31131
|
init_cjs_shims();
|
|
31022
|
-
var
|
|
31132
|
+
var import_ethers3 = require("ethers");
|
|
31023
31133
|
var import_fs3 = require("fs");
|
|
31024
31134
|
var import_path2 = require("path");
|
|
31025
31135
|
var import_crypto = require("crypto");
|
|
@@ -31064,7 +31174,7 @@ function createWallet(options = {}) {
|
|
|
31064
31174
|
}
|
|
31065
31175
|
}
|
|
31066
31176
|
try {
|
|
31067
|
-
const wallet =
|
|
31177
|
+
const wallet = import_ethers3.ethers.Wallet.createRandom();
|
|
31068
31178
|
const walletData = {
|
|
31069
31179
|
address: wallet.address,
|
|
31070
31180
|
label: options.label,
|
|
@@ -31119,26 +31229,26 @@ function loadWallet(options = {}) {
|
|
|
31119
31229
|
}
|
|
31120
31230
|
}
|
|
31121
31231
|
function getWalletAddress(storagePath) {
|
|
31122
|
-
const
|
|
31123
|
-
if (!(0, import_fs3.existsSync)(
|
|
31232
|
+
const path3 = storagePath || (0, import_path2.join)(DEFAULT_STORAGE_DIR, DEFAULT_STORAGE_FILE);
|
|
31233
|
+
if (!(0, import_fs3.existsSync)(path3)) {
|
|
31124
31234
|
return null;
|
|
31125
31235
|
}
|
|
31126
31236
|
try {
|
|
31127
|
-
const data = JSON.parse((0, import_fs3.readFileSync)(
|
|
31237
|
+
const data = JSON.parse((0, import_fs3.readFileSync)(path3, "utf8"));
|
|
31128
31238
|
return data.address;
|
|
31129
31239
|
} catch {
|
|
31130
31240
|
return null;
|
|
31131
31241
|
}
|
|
31132
31242
|
}
|
|
31133
31243
|
function walletExists(storagePath) {
|
|
31134
|
-
const
|
|
31135
|
-
return (0, import_fs3.existsSync)(
|
|
31244
|
+
const path3 = storagePath || (0, import_path2.join)(DEFAULT_STORAGE_DIR, DEFAULT_STORAGE_FILE);
|
|
31245
|
+
return (0, import_fs3.existsSync)(path3);
|
|
31136
31246
|
}
|
|
31137
31247
|
|
|
31138
31248
|
// src/verify/index.ts
|
|
31139
31249
|
init_cjs_shims();
|
|
31140
|
-
var
|
|
31141
|
-
var TRANSFER_EVENT_TOPIC =
|
|
31250
|
+
var import_ethers4 = require("ethers");
|
|
31251
|
+
var TRANSFER_EVENT_TOPIC = import_ethers4.ethers.id("Transfer(address,address,uint256)");
|
|
31142
31252
|
async function verifyPayment(params) {
|
|
31143
31253
|
const { txHash, expectedAmount, expectedTo } = params;
|
|
31144
31254
|
let chain2;
|
|
@@ -31155,7 +31265,7 @@ async function verifyPayment(params) {
|
|
|
31155
31265
|
return { verified: false, error: `Unsupported chain: ${params.chain}` };
|
|
31156
31266
|
}
|
|
31157
31267
|
try {
|
|
31158
|
-
const provider = new
|
|
31268
|
+
const provider = new import_ethers4.ethers.JsonRpcProvider(chain2.rpc);
|
|
31159
31269
|
const receipt = await provider.getTransactionReceipt(txHash);
|
|
31160
31270
|
if (!receipt) {
|
|
31161
31271
|
return { verified: false, error: "Transaction not found or not confirmed" };
|
|
@@ -31215,7 +31325,7 @@ async function getTransactionStatus(txHash, chain2 = "base") {
|
|
|
31215
31325
|
return { status: "not_found" };
|
|
31216
31326
|
}
|
|
31217
31327
|
try {
|
|
31218
|
-
const provider = new
|
|
31328
|
+
const provider = new import_ethers4.ethers.JsonRpcProvider(chainConfig.rpc);
|
|
31219
31329
|
const receipt = await provider.getTransactionReceipt(txHash);
|
|
31220
31330
|
if (!receipt) {
|
|
31221
31331
|
const tx = await provider.getTransaction(txHash);
|
|
@@ -31252,7 +31362,7 @@ async function waitForTransaction(txHash, chain2 = "base", confirmations = 1, ti
|
|
|
31252
31362
|
} catch (e) {
|
|
31253
31363
|
return { verified: false, confirmed: false, error: `Unsupported chain: ${chain2}` };
|
|
31254
31364
|
}
|
|
31255
|
-
const provider = new
|
|
31365
|
+
const provider = new import_ethers4.ethers.JsonRpcProvider(chainConfig.rpc);
|
|
31256
31366
|
try {
|
|
31257
31367
|
const receipt = await provider.waitForTransaction(txHash, confirmations, timeoutMs);
|
|
31258
31368
|
if (!receipt) {
|
|
@@ -31275,8 +31385,8 @@ async function waitForTransaction(txHash, chain2 = "base", confirmations = 1, ti
|
|
|
31275
31385
|
// src/cdp/index.ts
|
|
31276
31386
|
init_cjs_shims();
|
|
31277
31387
|
var fs = __toESM(require("fs"));
|
|
31278
|
-
var
|
|
31279
|
-
var DEFAULT_STORAGE_DIR2 =
|
|
31388
|
+
var path2 = __toESM(require("path"));
|
|
31389
|
+
var DEFAULT_STORAGE_DIR2 = path2.join(process.env.HOME || ".", ".moltspay");
|
|
31280
31390
|
var CDP_CONFIG_FILE = "cdp-wallet.json";
|
|
31281
31391
|
function isCDPAvailable() {
|
|
31282
31392
|
try {
|
|
@@ -31298,7 +31408,7 @@ function getCDPCredentials(config) {
|
|
|
31298
31408
|
async function initCDPWallet(config = {}) {
|
|
31299
31409
|
const storageDir = config.storageDir || DEFAULT_STORAGE_DIR2;
|
|
31300
31410
|
const chain2 = config.chain || "base";
|
|
31301
|
-
const storagePath =
|
|
31411
|
+
const storagePath = path2.join(storageDir, CDP_CONFIG_FILE);
|
|
31302
31412
|
if (fs.existsSync(storagePath)) {
|
|
31303
31413
|
try {
|
|
31304
31414
|
const data = JSON.parse(fs.readFileSync(storagePath, "utf-8"));
|
|
@@ -31360,7 +31470,7 @@ async function initCDPWallet(config = {}) {
|
|
|
31360
31470
|
}
|
|
31361
31471
|
function loadCDPWallet(config = {}) {
|
|
31362
31472
|
const storageDir = config.storageDir || DEFAULT_STORAGE_DIR2;
|
|
31363
|
-
const storagePath =
|
|
31473
|
+
const storagePath = path2.join(storageDir, CDP_CONFIG_FILE);
|
|
31364
31474
|
if (!fs.existsSync(storagePath)) {
|
|
31365
31475
|
return null;
|
|
31366
31476
|
}
|
|
@@ -31393,9 +31503,9 @@ var CDPWallet = class {
|
|
|
31393
31503
|
* Get USDC balance
|
|
31394
31504
|
*/
|
|
31395
31505
|
async getBalance() {
|
|
31396
|
-
const { ethers:
|
|
31397
|
-
const provider = new
|
|
31398
|
-
const usdcContract = new
|
|
31506
|
+
const { ethers: ethers5 } = await import("ethers");
|
|
31507
|
+
const provider = new ethers5.JsonRpcProvider(this.chainConfig.rpc);
|
|
31508
|
+
const usdcContract = new ethers5.Contract(
|
|
31399
31509
|
this.chainConfig.usdc,
|
|
31400
31510
|
["function balanceOf(address) view returns (uint256)"],
|
|
31401
31511
|
provider
|
|
@@ -31406,7 +31516,7 @@ var CDPWallet = class {
|
|
|
31406
31516
|
]);
|
|
31407
31517
|
return {
|
|
31408
31518
|
usdc: (Number(usdcBalance) / 1e6).toFixed(2),
|
|
31409
|
-
eth:
|
|
31519
|
+
eth: ethers5.formatEther(ethBalance)
|
|
31410
31520
|
};
|
|
31411
31521
|
}
|
|
31412
31522
|
/**
|
|
@@ -31424,7 +31534,7 @@ var CDPWallet = class {
|
|
|
31424
31534
|
}
|
|
31425
31535
|
try {
|
|
31426
31536
|
const { CdpClient } = await import("@coinbase/cdp-sdk");
|
|
31427
|
-
const { ethers:
|
|
31537
|
+
const { ethers: ethers5 } = await import("ethers");
|
|
31428
31538
|
const cdp = new CdpClient({
|
|
31429
31539
|
apiKeyId: creds.apiKeyId,
|
|
31430
31540
|
apiKeySecret: creds.apiKeySecret,
|
|
@@ -31432,7 +31542,7 @@ var CDPWallet = class {
|
|
|
31432
31542
|
});
|
|
31433
31543
|
const account = await cdp.evm.getAccount({ address: this.address });
|
|
31434
31544
|
const amountWei = BigInt(Math.floor(params.amount * 1e6));
|
|
31435
|
-
const iface = new
|
|
31545
|
+
const iface = new ethers5.Interface([
|
|
31436
31546
|
"function transfer(address to, uint256 amount) returns (bool)"
|
|
31437
31547
|
]);
|
|
31438
31548
|
const callData = iface.encodeFunctionData("transfer", [params.to, amountWei]);
|