moltspay 0.7.1 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +270 -262
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +272 -264
- package/dist/cli/index.mjs.map +1 -1
- package/dist/client/index.d.mts +11 -5
- package/dist/client/index.d.ts +11 -5
- package/dist/client/index.js +99 -68
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +96 -55
- package/dist/client/index.mjs.map +1 -1
- package/dist/index.js +387 -321
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +391 -325
- package/dist/index.mjs.map +1 -1
- package/dist/server/index.d.mts +17 -8
- package/dist/server/index.d.ts +17 -8
- package/dist/server/index.js +145 -194
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +145 -194
- package/dist/server/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -30332,9 +30332,6 @@ init_esm_shims();
|
|
|
30332
30332
|
init_esm_shims();
|
|
30333
30333
|
import { readFileSync } from "fs";
|
|
30334
30334
|
import { createServer } from "http";
|
|
30335
|
-
|
|
30336
|
-
// src/verify/index.ts
|
|
30337
|
-
init_esm_shims();
|
|
30338
30335
|
import { ethers } from "ethers";
|
|
30339
30336
|
|
|
30340
30337
|
// src/chains/index.ts
|
|
@@ -30415,165 +30412,41 @@ var ERC20_ABI = [
|
|
|
30415
30412
|
"event Approval(address indexed owner, address indexed spender, uint256 value)"
|
|
30416
30413
|
];
|
|
30417
30414
|
|
|
30418
|
-
// src/verify/index.ts
|
|
30419
|
-
var TRANSFER_EVENT_TOPIC = ethers.id("Transfer(address,address,uint256)");
|
|
30420
|
-
async function verifyPayment(params) {
|
|
30421
|
-
const { txHash, expectedAmount, expectedTo } = params;
|
|
30422
|
-
let chain2;
|
|
30423
|
-
try {
|
|
30424
|
-
if (typeof params.chain === "number") {
|
|
30425
|
-
chain2 = getChainById(params.chain);
|
|
30426
|
-
} else {
|
|
30427
|
-
chain2 = getChain(params.chain || "base");
|
|
30428
|
-
}
|
|
30429
|
-
if (!chain2) {
|
|
30430
|
-
return { verified: false, error: `Unsupported chain: ${params.chain}` };
|
|
30431
|
-
}
|
|
30432
|
-
} catch (e) {
|
|
30433
|
-
return { verified: false, error: `Unsupported chain: ${params.chain}` };
|
|
30434
|
-
}
|
|
30435
|
-
try {
|
|
30436
|
-
const provider = new ethers.JsonRpcProvider(chain2.rpc);
|
|
30437
|
-
const receipt = await provider.getTransactionReceipt(txHash);
|
|
30438
|
-
if (!receipt) {
|
|
30439
|
-
return { verified: false, error: "Transaction not found or not confirmed" };
|
|
30440
|
-
}
|
|
30441
|
-
if (receipt.status !== 1) {
|
|
30442
|
-
return { verified: false, error: "Transaction failed" };
|
|
30443
|
-
}
|
|
30444
|
-
const usdcAddress = chain2.usdc?.toLowerCase();
|
|
30445
|
-
if (!usdcAddress) {
|
|
30446
|
-
return { verified: false, error: `Chain ${chain2.name} USDC address not configured` };
|
|
30447
|
-
}
|
|
30448
|
-
for (const log of receipt.logs) {
|
|
30449
|
-
if (log.address.toLowerCase() !== usdcAddress) {
|
|
30450
|
-
continue;
|
|
30451
|
-
}
|
|
30452
|
-
if (log.topics.length < 3 || log.topics[0] !== TRANSFER_EVENT_TOPIC) {
|
|
30453
|
-
continue;
|
|
30454
|
-
}
|
|
30455
|
-
const from = "0x" + log.topics[1].slice(-40);
|
|
30456
|
-
const to = "0x" + log.topics[2].slice(-40);
|
|
30457
|
-
const amountRaw = BigInt(log.data);
|
|
30458
|
-
const amount = Number(amountRaw) / 1e6;
|
|
30459
|
-
if (expectedTo && to.toLowerCase() !== expectedTo.toLowerCase()) {
|
|
30460
|
-
continue;
|
|
30461
|
-
}
|
|
30462
|
-
if (amount < expectedAmount) {
|
|
30463
|
-
return {
|
|
30464
|
-
verified: false,
|
|
30465
|
-
error: `Insufficient amount: received ${amount} USDC, expected ${expectedAmount} USDC`,
|
|
30466
|
-
amount,
|
|
30467
|
-
from,
|
|
30468
|
-
to,
|
|
30469
|
-
txHash,
|
|
30470
|
-
blockNumber: receipt.blockNumber
|
|
30471
|
-
};
|
|
30472
|
-
}
|
|
30473
|
-
return {
|
|
30474
|
-
verified: true,
|
|
30475
|
-
amount,
|
|
30476
|
-
from,
|
|
30477
|
-
to,
|
|
30478
|
-
txHash,
|
|
30479
|
-
blockNumber: receipt.blockNumber
|
|
30480
|
-
};
|
|
30481
|
-
}
|
|
30482
|
-
return { verified: false, error: "No USDC transfer found" };
|
|
30483
|
-
} catch (e) {
|
|
30484
|
-
return { verified: false, error: e.message || String(e) };
|
|
30485
|
-
}
|
|
30486
|
-
}
|
|
30487
|
-
async function getTransactionStatus(txHash, chain2 = "base") {
|
|
30488
|
-
let chainConfig;
|
|
30489
|
-
try {
|
|
30490
|
-
chainConfig = typeof chain2 === "number" ? getChainById(chain2) : getChain(chain2);
|
|
30491
|
-
if (!chainConfig) return { status: "not_found" };
|
|
30492
|
-
} catch {
|
|
30493
|
-
return { status: "not_found" };
|
|
30494
|
-
}
|
|
30495
|
-
try {
|
|
30496
|
-
const provider = new ethers.JsonRpcProvider(chainConfig.rpc);
|
|
30497
|
-
const receipt = await provider.getTransactionReceipt(txHash);
|
|
30498
|
-
if (!receipt) {
|
|
30499
|
-
const tx = await provider.getTransaction(txHash);
|
|
30500
|
-
if (tx) {
|
|
30501
|
-
return { status: "pending" };
|
|
30502
|
-
}
|
|
30503
|
-
return { status: "not_found" };
|
|
30504
|
-
}
|
|
30505
|
-
const currentBlock = await provider.getBlockNumber();
|
|
30506
|
-
const confirmations = currentBlock - receipt.blockNumber;
|
|
30507
|
-
if (receipt.status === 1) {
|
|
30508
|
-
return {
|
|
30509
|
-
status: "confirmed",
|
|
30510
|
-
blockNumber: receipt.blockNumber,
|
|
30511
|
-
confirmations
|
|
30512
|
-
};
|
|
30513
|
-
} else {
|
|
30514
|
-
return {
|
|
30515
|
-
status: "failed",
|
|
30516
|
-
blockNumber: receipt.blockNumber
|
|
30517
|
-
};
|
|
30518
|
-
}
|
|
30519
|
-
} catch {
|
|
30520
|
-
return { status: "not_found" };
|
|
30521
|
-
}
|
|
30522
|
-
}
|
|
30523
|
-
async function waitForTransaction(txHash, chain2 = "base", confirmations = 1, timeoutMs = 6e4) {
|
|
30524
|
-
let chainConfig;
|
|
30525
|
-
try {
|
|
30526
|
-
chainConfig = typeof chain2 === "number" ? getChainById(chain2) : getChain(chain2);
|
|
30527
|
-
if (!chainConfig) {
|
|
30528
|
-
return { verified: false, confirmed: false, error: `Unsupported chain: ${chain2}` };
|
|
30529
|
-
}
|
|
30530
|
-
} catch (e) {
|
|
30531
|
-
return { verified: false, confirmed: false, error: `Unsupported chain: ${chain2}` };
|
|
30532
|
-
}
|
|
30533
|
-
const provider = new ethers.JsonRpcProvider(chainConfig.rpc);
|
|
30534
|
-
try {
|
|
30535
|
-
const receipt = await provider.waitForTransaction(txHash, confirmations, timeoutMs);
|
|
30536
|
-
if (!receipt) {
|
|
30537
|
-
return { verified: false, confirmed: false, error: "Timeout waiting" };
|
|
30538
|
-
}
|
|
30539
|
-
if (receipt.status !== 1) {
|
|
30540
|
-
return { verified: false, confirmed: true, error: "Transaction failed" };
|
|
30541
|
-
}
|
|
30542
|
-
return {
|
|
30543
|
-
verified: true,
|
|
30544
|
-
confirmed: true,
|
|
30545
|
-
txHash,
|
|
30546
|
-
blockNumber: receipt.blockNumber
|
|
30547
|
-
};
|
|
30548
|
-
} catch (e) {
|
|
30549
|
-
return { verified: false, confirmed: false, error: e.message || String(e) };
|
|
30550
|
-
}
|
|
30551
|
-
}
|
|
30552
|
-
|
|
30553
30415
|
// src/server/types.ts
|
|
30554
30416
|
init_esm_shims();
|
|
30555
30417
|
|
|
30556
30418
|
// src/server/index.ts
|
|
30557
|
-
|
|
30558
|
-
|
|
30559
|
-
|
|
30419
|
+
var X402_VERSION = 2;
|
|
30420
|
+
var PAYMENT_REQUIRED_HEADER = "x-payment-required";
|
|
30421
|
+
var PAYMENT_HEADER = "x-payment";
|
|
30560
30422
|
var MoltsPayServer = class {
|
|
30561
30423
|
manifest;
|
|
30562
30424
|
skills = /* @__PURE__ */ new Map();
|
|
30563
|
-
charges = /* @__PURE__ */ new Map();
|
|
30564
30425
|
options;
|
|
30426
|
+
provider = null;
|
|
30427
|
+
wallet = null;
|
|
30565
30428
|
constructor(servicesPath, options = {}) {
|
|
30566
30429
|
const content = readFileSync(servicesPath, "utf-8");
|
|
30567
30430
|
this.manifest = JSON.parse(content);
|
|
30568
30431
|
this.options = {
|
|
30569
30432
|
port: options.port || 3e3,
|
|
30570
30433
|
host: options.host || "0.0.0.0",
|
|
30571
|
-
|
|
30572
|
-
// 5 minutes
|
|
30434
|
+
privateKey: options.privateKey || process.env.MOLTSPAY_PRIVATE_KEY
|
|
30573
30435
|
};
|
|
30436
|
+
if (this.options.privateKey) {
|
|
30437
|
+
try {
|
|
30438
|
+
const chain2 = getChain(this.manifest.provider.chain);
|
|
30439
|
+
this.provider = new ethers.JsonRpcProvider(chain2.rpc);
|
|
30440
|
+
this.wallet = new ethers.Wallet(this.options.privateKey, this.provider);
|
|
30441
|
+
console.log(`[MoltsPay] Payment wallet: ${this.wallet.address}`);
|
|
30442
|
+
} catch (err) {
|
|
30443
|
+
console.warn("[MoltsPay] Warning: Could not initialize wallet for payment claims");
|
|
30444
|
+
}
|
|
30445
|
+
}
|
|
30574
30446
|
console.log(`[MoltsPay] Loaded ${this.manifest.services.length} services from ${servicesPath}`);
|
|
30575
30447
|
console.log(`[MoltsPay] Provider: ${this.manifest.provider.name}`);
|
|
30576
|
-
console.log(`[MoltsPay]
|
|
30448
|
+
console.log(`[MoltsPay] Receive wallet: ${this.manifest.provider.wallet}`);
|
|
30449
|
+
console.log(`[MoltsPay] Protocol: x402 (gasless, pay-for-success)`);
|
|
30577
30450
|
}
|
|
30578
30451
|
/**
|
|
30579
30452
|
* Register a skill handler for a service
|
|
@@ -30600,10 +30473,8 @@ var MoltsPayServer = class {
|
|
|
30600
30473
|
server.listen(p, this.options.host, () => {
|
|
30601
30474
|
console.log(`[MoltsPay] Server listening on http://${this.options.host}:${p}`);
|
|
30602
30475
|
console.log(`[MoltsPay] Endpoints:`);
|
|
30603
|
-
console.log(` GET /services
|
|
30604
|
-
console.log(` POST /
|
|
30605
|
-
console.log(` POST /verify - Verify payment & get result`);
|
|
30606
|
-
console.log(` GET /status/:id - Check charge status`);
|
|
30476
|
+
console.log(` GET /services - List available services`);
|
|
30477
|
+
console.log(` POST /execute - Execute service (x402 payment)`);
|
|
30607
30478
|
});
|
|
30608
30479
|
}
|
|
30609
30480
|
async handleRequest(req, res) {
|
|
@@ -30612,7 +30483,8 @@ var MoltsPayServer = class {
|
|
|
30612
30483
|
const method = req.method || "GET";
|
|
30613
30484
|
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
30614
30485
|
res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
|
30615
|
-
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
|
|
30486
|
+
res.setHeader("Access-Control-Allow-Headers", "Content-Type, X-Payment");
|
|
30487
|
+
res.setHeader("Access-Control-Expose-Headers", "X-Payment-Required, X-Payment-Response");
|
|
30616
30488
|
if (method === "OPTIONS") {
|
|
30617
30489
|
res.writeHead(204);
|
|
30618
30490
|
res.end();
|
|
@@ -30622,17 +30494,10 @@ var MoltsPayServer = class {
|
|
|
30622
30494
|
if (method === "GET" && path3 === "/services") {
|
|
30623
30495
|
return this.handleGetServices(res);
|
|
30624
30496
|
}
|
|
30625
|
-
if (method === "POST" && path3 === "/
|
|
30497
|
+
if (method === "POST" && path3 === "/execute") {
|
|
30626
30498
|
const body = await this.readBody(req);
|
|
30627
|
-
|
|
30628
|
-
|
|
30629
|
-
if (method === "POST" && path3 === "/verify") {
|
|
30630
|
-
const body = await this.readBody(req);
|
|
30631
|
-
return this.handleVerify(body, res);
|
|
30632
|
-
}
|
|
30633
|
-
if (method === "GET" && path3.startsWith("/status/")) {
|
|
30634
|
-
const chargeId = path3.replace("/status/", "");
|
|
30635
|
-
return this.handleStatus(chargeId, res);
|
|
30499
|
+
const paymentHeader = req.headers[PAYMENT_HEADER];
|
|
30500
|
+
return this.handleExecute(body, paymentHeader, res);
|
|
30636
30501
|
}
|
|
30637
30502
|
this.sendJson(res, 404, { error: "Not found" });
|
|
30638
30503
|
} catch (err) {
|
|
@@ -30644,6 +30509,7 @@ var MoltsPayServer = class {
|
|
|
30644
30509
|
* GET /services - List available services
|
|
30645
30510
|
*/
|
|
30646
30511
|
handleGetServices(res) {
|
|
30512
|
+
const chain2 = getChain(this.manifest.provider.chain);
|
|
30647
30513
|
const services = this.manifest.services.map((s) => ({
|
|
30648
30514
|
id: s.id,
|
|
30649
30515
|
name: s.name,
|
|
@@ -30656,14 +30522,20 @@ var MoltsPayServer = class {
|
|
|
30656
30522
|
}));
|
|
30657
30523
|
this.sendJson(res, 200, {
|
|
30658
30524
|
provider: this.manifest.provider,
|
|
30659
|
-
services
|
|
30525
|
+
services,
|
|
30526
|
+
x402: {
|
|
30527
|
+
version: X402_VERSION,
|
|
30528
|
+
network: `eip155:${chain2.chainId}`,
|
|
30529
|
+
schemes: ["exact"]
|
|
30530
|
+
}
|
|
30660
30531
|
});
|
|
30661
30532
|
}
|
|
30662
30533
|
/**
|
|
30663
|
-
* POST /
|
|
30534
|
+
* POST /execute - Execute service with x402 payment
|
|
30664
30535
|
* Body: { service: string, params: object }
|
|
30536
|
+
* Header: X-Payment (optional - if missing, returns 402)
|
|
30665
30537
|
*/
|
|
30666
|
-
|
|
30538
|
+
async handleExecute(body, paymentHeader, res) {
|
|
30667
30539
|
const { service, params } = body;
|
|
30668
30540
|
if (!service) {
|
|
30669
30541
|
return this.sendJson(res, 400, { error: "Missing service" });
|
|
@@ -30677,113 +30549,129 @@ var MoltsPayServer = class {
|
|
|
30677
30549
|
return this.sendJson(res, 400, { error: `Missing required param: ${key}` });
|
|
30678
30550
|
}
|
|
30679
30551
|
}
|
|
30680
|
-
|
|
30681
|
-
|
|
30682
|
-
|
|
30683
|
-
|
|
30684
|
-
|
|
30685
|
-
|
|
30686
|
-
|
|
30687
|
-
|
|
30688
|
-
|
|
30689
|
-
|
|
30690
|
-
|
|
30691
|
-
|
|
30692
|
-
|
|
30693
|
-
|
|
30694
|
-
|
|
30695
|
-
|
|
30696
|
-
|
|
30697
|
-
|
|
30698
|
-
|
|
30699
|
-
|
|
30700
|
-
|
|
30701
|
-
|
|
30702
|
-
|
|
30703
|
-
|
|
30704
|
-
|
|
30552
|
+
if (!paymentHeader) {
|
|
30553
|
+
return this.sendPaymentRequired(skill.config, res);
|
|
30554
|
+
}
|
|
30555
|
+
let payment;
|
|
30556
|
+
try {
|
|
30557
|
+
const decoded = Buffer.from(paymentHeader, "base64").toString("utf-8");
|
|
30558
|
+
payment = JSON.parse(decoded);
|
|
30559
|
+
} catch {
|
|
30560
|
+
return this.sendJson(res, 400, { error: "Invalid X-Payment header" });
|
|
30561
|
+
}
|
|
30562
|
+
const validation = this.validatePayment(payment, skill.config);
|
|
30563
|
+
if (!validation.valid) {
|
|
30564
|
+
return this.sendJson(res, 402, { error: validation.error });
|
|
30565
|
+
}
|
|
30566
|
+
console.log(`[MoltsPay] Executing skill: ${service}`);
|
|
30567
|
+
let result;
|
|
30568
|
+
try {
|
|
30569
|
+
result = await skill.handler(params || {});
|
|
30570
|
+
} catch (err) {
|
|
30571
|
+
console.error("[MoltsPay] Skill execution failed:", err.message);
|
|
30572
|
+
return this.sendJson(res, 500, {
|
|
30573
|
+
error: "Service execution failed",
|
|
30574
|
+
message: err.message
|
|
30575
|
+
});
|
|
30576
|
+
}
|
|
30577
|
+
console.log(`[MoltsPay] Skill succeeded, claiming payment...`);
|
|
30578
|
+
let txHash = null;
|
|
30579
|
+
try {
|
|
30580
|
+
txHash = await this.claimPayment(payment);
|
|
30581
|
+
console.log(`[MoltsPay] Payment claimed: ${txHash}`);
|
|
30582
|
+
} catch (err) {
|
|
30583
|
+
console.error("[MoltsPay] Payment claim failed:", err.message);
|
|
30584
|
+
}
|
|
30585
|
+
this.sendJson(res, 200, {
|
|
30586
|
+
success: true,
|
|
30587
|
+
result,
|
|
30588
|
+
payment: txHash ? { txHash, status: "claimed" } : { status: "pending" }
|
|
30705
30589
|
});
|
|
30706
30590
|
}
|
|
30707
30591
|
/**
|
|
30708
|
-
*
|
|
30709
|
-
* Body: { chargeId: string, txHash: string }
|
|
30592
|
+
* Return 402 with x402 payment requirements
|
|
30710
30593
|
*/
|
|
30711
|
-
|
|
30712
|
-
const
|
|
30713
|
-
|
|
30714
|
-
|
|
30594
|
+
sendPaymentRequired(config, res) {
|
|
30595
|
+
const chain2 = getChain(this.manifest.provider.chain);
|
|
30596
|
+
const amountInUnits = Math.floor(config.price * 1e6).toString();
|
|
30597
|
+
const requirements = [{
|
|
30598
|
+
scheme: "exact",
|
|
30599
|
+
network: `eip155:${chain2.chainId}`,
|
|
30600
|
+
maxAmountRequired: amountInUnits,
|
|
30601
|
+
resource: this.manifest.provider.wallet,
|
|
30602
|
+
description: `${config.name} - $${config.price} ${config.currency}`
|
|
30603
|
+
}];
|
|
30604
|
+
const encoded = Buffer.from(JSON.stringify(requirements)).toString("base64");
|
|
30605
|
+
res.writeHead(402, {
|
|
30606
|
+
"Content-Type": "application/json",
|
|
30607
|
+
[PAYMENT_REQUIRED_HEADER]: encoded
|
|
30608
|
+
});
|
|
30609
|
+
res.end(JSON.stringify({
|
|
30610
|
+
error: "Payment required",
|
|
30611
|
+
message: `Service requires $${config.price} ${config.currency}`,
|
|
30612
|
+
x402: requirements[0]
|
|
30613
|
+
}, null, 2));
|
|
30614
|
+
}
|
|
30615
|
+
/**
|
|
30616
|
+
* Validate x402 payment payload
|
|
30617
|
+
*/
|
|
30618
|
+
validatePayment(payment, config) {
|
|
30619
|
+
if (payment.x402Version !== X402_VERSION) {
|
|
30620
|
+
return { valid: false, error: `Unsupported x402 version: ${payment.x402Version}` };
|
|
30715
30621
|
}
|
|
30716
|
-
|
|
30717
|
-
|
|
30718
|
-
return this.sendJson(res, 404, { error: "Charge not found" });
|
|
30622
|
+
if (payment.scheme !== "exact") {
|
|
30623
|
+
return { valid: false, error: `Unsupported scheme: ${payment.scheme}` };
|
|
30719
30624
|
}
|
|
30720
|
-
|
|
30721
|
-
|
|
30722
|
-
|
|
30625
|
+
const chain2 = getChain(this.manifest.provider.chain);
|
|
30626
|
+
const expectedNetwork = `eip155:${chain2.chainId}`;
|
|
30627
|
+
if (payment.network !== expectedNetwork) {
|
|
30628
|
+
return { valid: false, error: `Network mismatch: expected ${expectedNetwork}` };
|
|
30723
30629
|
}
|
|
30724
|
-
|
|
30725
|
-
|
|
30726
|
-
|
|
30727
|
-
result: charge.result
|
|
30728
|
-
});
|
|
30630
|
+
const auth = payment.payload.authorization;
|
|
30631
|
+
if (auth.to.toLowerCase() !== this.manifest.provider.wallet.toLowerCase()) {
|
|
30632
|
+
return { valid: false, error: "Payment recipient mismatch" };
|
|
30729
30633
|
}
|
|
30730
|
-
|
|
30731
|
-
|
|
30732
|
-
|
|
30733
|
-
|
|
30734
|
-
|
|
30735
|
-
|
|
30736
|
-
}
|
|
30737
|
-
|
|
30738
|
-
|
|
30739
|
-
|
|
30740
|
-
error: "Payment verification failed",
|
|
30741
|
-
reason: verification.error
|
|
30742
|
-
});
|
|
30743
|
-
}
|
|
30744
|
-
charge.status = "paid";
|
|
30745
|
-
charge.txHash = txHash;
|
|
30746
|
-
charge.paidAt = Date.now();
|
|
30747
|
-
const skill = this.skills.get(charge.service);
|
|
30748
|
-
console.log(`[MoltsPay] Executing skill: ${charge.service}`);
|
|
30749
|
-
const result = await skill.handler(charge.params);
|
|
30750
|
-
charge.status = "completed";
|
|
30751
|
-
charge.result = result;
|
|
30752
|
-
charge.completedAt = Date.now();
|
|
30753
|
-
this.sendJson(res, 200, {
|
|
30754
|
-
status: "completed",
|
|
30755
|
-
chargeId,
|
|
30756
|
-
txHash,
|
|
30757
|
-
result
|
|
30758
|
-
});
|
|
30759
|
-
} catch (err) {
|
|
30760
|
-
console.error("[MoltsPay] Skill execution error:", err);
|
|
30761
|
-
charge.status = "failed";
|
|
30762
|
-
this.sendJson(res, 500, {
|
|
30763
|
-
error: "Skill execution failed",
|
|
30764
|
-
message: err.message
|
|
30765
|
-
});
|
|
30634
|
+
const amount = Number(auth.value) / 1e6;
|
|
30635
|
+
if (amount < config.price) {
|
|
30636
|
+
return { valid: false, error: `Insufficient amount: $${amount} < $${config.price}` };
|
|
30637
|
+
}
|
|
30638
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
30639
|
+
if (Number(auth.validBefore) < now) {
|
|
30640
|
+
return { valid: false, error: "Payment authorization expired" };
|
|
30641
|
+
}
|
|
30642
|
+
if (Number(auth.validAfter) > now) {
|
|
30643
|
+
return { valid: false, error: "Payment authorization not yet valid" };
|
|
30766
30644
|
}
|
|
30645
|
+
return { valid: true };
|
|
30767
30646
|
}
|
|
30768
30647
|
/**
|
|
30769
|
-
*
|
|
30648
|
+
* Claim payment using transferWithAuthorization
|
|
30770
30649
|
*/
|
|
30771
|
-
|
|
30772
|
-
|
|
30773
|
-
|
|
30774
|
-
return this.sendJson(res, 404, { error: "Charge not found" });
|
|
30650
|
+
async claimPayment(payment) {
|
|
30651
|
+
if (!this.wallet || !this.provider) {
|
|
30652
|
+
throw new Error("Wallet not configured for payment claims");
|
|
30775
30653
|
}
|
|
30776
|
-
this.
|
|
30777
|
-
|
|
30778
|
-
|
|
30779
|
-
|
|
30780
|
-
|
|
30781
|
-
|
|
30782
|
-
|
|
30783
|
-
|
|
30784
|
-
|
|
30785
|
-
|
|
30786
|
-
|
|
30654
|
+
const chain2 = getChain(this.manifest.provider.chain);
|
|
30655
|
+
const auth = payment.payload.authorization;
|
|
30656
|
+
const sig = payment.payload.signature;
|
|
30657
|
+
const { r, s, v } = ethers.Signature.from(sig);
|
|
30658
|
+
const usdcAbi = [
|
|
30659
|
+
"function transferWithAuthorization(address from, address to, uint256 value, uint256 validAfter, uint256 validBefore, bytes32 nonce, uint8 v, bytes32 r, bytes32 s)"
|
|
30660
|
+
];
|
|
30661
|
+
const usdc = new ethers.Contract(chain2.usdc, usdcAbi, this.wallet);
|
|
30662
|
+
const tx = await usdc.transferWithAuthorization(
|
|
30663
|
+
auth.from,
|
|
30664
|
+
auth.to,
|
|
30665
|
+
auth.value,
|
|
30666
|
+
auth.validAfter,
|
|
30667
|
+
auth.validBefore,
|
|
30668
|
+
auth.nonce,
|
|
30669
|
+
v,
|
|
30670
|
+
r,
|
|
30671
|
+
s
|
|
30672
|
+
);
|
|
30673
|
+
const receipt = await tx.wait();
|
|
30674
|
+
return receipt.hash;
|
|
30787
30675
|
}
|
|
30788
30676
|
async readBody(req) {
|
|
30789
30677
|
return new Promise((resolve, reject) => {
|
|
@@ -30810,12 +30698,15 @@ init_esm_shims();
|
|
|
30810
30698
|
import { existsSync, readFileSync as readFileSync2, writeFileSync, mkdirSync } from "fs";
|
|
30811
30699
|
import { homedir } from "os";
|
|
30812
30700
|
import { join } from "path";
|
|
30813
|
-
import { Wallet } from "ethers";
|
|
30701
|
+
import { Wallet, ethers as ethers2 } from "ethers";
|
|
30814
30702
|
|
|
30815
30703
|
// src/client/types.ts
|
|
30816
30704
|
init_esm_shims();
|
|
30817
30705
|
|
|
30818
30706
|
// src/client/index.ts
|
|
30707
|
+
var X402_VERSION2 = 2;
|
|
30708
|
+
var PAYMENT_REQUIRED_HEADER2 = "x-payment-required";
|
|
30709
|
+
var PAYMENT_HEADER2 = "x-payment";
|
|
30819
30710
|
var DEFAULT_CONFIG = {
|
|
30820
30711
|
chain: "base",
|
|
30821
30712
|
limits: {
|
|
@@ -30879,43 +30770,112 @@ var MoltsPayClient = class {
|
|
|
30879
30770
|
return res.json();
|
|
30880
30771
|
}
|
|
30881
30772
|
/**
|
|
30882
|
-
* Pay for a service and get the result
|
|
30773
|
+
* Pay for a service and get the result (x402 protocol)
|
|
30774
|
+
*
|
|
30775
|
+
* This is GASLESS for the client - server pays gas to claim payment.
|
|
30776
|
+
* This is PAY-FOR-SUCCESS - payment only claimed if service succeeds.
|
|
30883
30777
|
*/
|
|
30884
30778
|
async pay(serverUrl, service, params) {
|
|
30885
|
-
if (!this.wallet) {
|
|
30779
|
+
if (!this.wallet || !this.walletData) {
|
|
30886
30780
|
throw new Error("Client not initialized. Run: npx moltspay init");
|
|
30887
30781
|
}
|
|
30888
|
-
|
|
30782
|
+
console.log(`[MoltsPay] Requesting service: ${service}`);
|
|
30783
|
+
const initialRes = await fetch(`${serverUrl}/execute`, {
|
|
30889
30784
|
method: "POST",
|
|
30890
30785
|
headers: { "Content-Type": "application/json" },
|
|
30891
30786
|
body: JSON.stringify({ service, params })
|
|
30892
30787
|
});
|
|
30893
|
-
if (
|
|
30894
|
-
const
|
|
30895
|
-
|
|
30788
|
+
if (initialRes.status !== 402) {
|
|
30789
|
+
const data = await initialRes.json();
|
|
30790
|
+
if (initialRes.ok && data.result) {
|
|
30791
|
+
return data.result;
|
|
30792
|
+
}
|
|
30793
|
+
throw new Error(data.error || "Unexpected response");
|
|
30794
|
+
}
|
|
30795
|
+
const paymentRequiredHeader = initialRes.headers.get(PAYMENT_REQUIRED_HEADER2);
|
|
30796
|
+
if (!paymentRequiredHeader) {
|
|
30797
|
+
throw new Error("Missing x-payment-required header");
|
|
30896
30798
|
}
|
|
30897
|
-
|
|
30898
|
-
|
|
30899
|
-
|
|
30900
|
-
|
|
30901
|
-
|
|
30902
|
-
|
|
30903
|
-
|
|
30799
|
+
let requirements;
|
|
30800
|
+
try {
|
|
30801
|
+
const decoded = Buffer.from(paymentRequiredHeader, "base64").toString("utf-8");
|
|
30802
|
+
requirements = JSON.parse(decoded);
|
|
30803
|
+
if (!Array.isArray(requirements)) {
|
|
30804
|
+
requirements = [requirements];
|
|
30805
|
+
}
|
|
30806
|
+
} catch {
|
|
30807
|
+
throw new Error("Invalid x-payment-required header");
|
|
30808
|
+
}
|
|
30809
|
+
const chain2 = getChain(this.config.chain);
|
|
30810
|
+
const network = `eip155:${chain2.chainId}`;
|
|
30811
|
+
const req = requirements.find((r) => r.scheme === "exact" && r.network === network);
|
|
30812
|
+
if (!req) {
|
|
30813
|
+
throw new Error(`No matching payment option for ${network}`);
|
|
30814
|
+
}
|
|
30815
|
+
const amount = Number(req.maxAmountRequired) / 1e6;
|
|
30816
|
+
this.checkLimits(amount);
|
|
30817
|
+
console.log(`[MoltsPay] Signing payment: $${amount} USDC (gasless)`);
|
|
30818
|
+
const authorization = await this.signEIP3009(req.resource, amount, chain2);
|
|
30819
|
+
const payload = {
|
|
30820
|
+
x402Version: X402_VERSION2,
|
|
30821
|
+
scheme: "exact",
|
|
30822
|
+
network,
|
|
30823
|
+
payload: authorization
|
|
30824
|
+
};
|
|
30825
|
+
const paymentHeader = Buffer.from(JSON.stringify(payload)).toString("base64");
|
|
30826
|
+
console.log(`[MoltsPay] Sending request with payment...`);
|
|
30827
|
+
const paidRes = await fetch(`${serverUrl}/execute`, {
|
|
30904
30828
|
method: "POST",
|
|
30905
|
-
headers: {
|
|
30906
|
-
|
|
30907
|
-
|
|
30908
|
-
|
|
30909
|
-
})
|
|
30829
|
+
headers: {
|
|
30830
|
+
"Content-Type": "application/json",
|
|
30831
|
+
[PAYMENT_HEADER2]: paymentHeader
|
|
30832
|
+
},
|
|
30833
|
+
body: JSON.stringify({ service, params })
|
|
30910
30834
|
});
|
|
30911
|
-
|
|
30912
|
-
|
|
30913
|
-
throw new Error(
|
|
30835
|
+
const result = await paidRes.json();
|
|
30836
|
+
if (!paidRes.ok) {
|
|
30837
|
+
throw new Error(result.error || "Service execution failed");
|
|
30914
30838
|
}
|
|
30915
|
-
|
|
30916
|
-
|
|
30839
|
+
this.recordSpending(amount);
|
|
30840
|
+
console.log(`[MoltsPay] Success! Payment: ${result.payment?.status || "claimed"}`);
|
|
30917
30841
|
return result.result;
|
|
30918
30842
|
}
|
|
30843
|
+
/**
|
|
30844
|
+
* Sign EIP-3009 transferWithAuthorization (GASLESS)
|
|
30845
|
+
* This only signs - no on-chain transaction, no gas needed.
|
|
30846
|
+
*/
|
|
30847
|
+
async signEIP3009(to, amount, chain2) {
|
|
30848
|
+
const validAfter = 0;
|
|
30849
|
+
const validBefore = Math.floor(Date.now() / 1e3) + 3600;
|
|
30850
|
+
const nonce = ethers2.hexlify(ethers2.randomBytes(32));
|
|
30851
|
+
const value = BigInt(Math.floor(amount * 1e6)).toString();
|
|
30852
|
+
const authorization = {
|
|
30853
|
+
from: this.wallet.address,
|
|
30854
|
+
to,
|
|
30855
|
+
value,
|
|
30856
|
+
validAfter: validAfter.toString(),
|
|
30857
|
+
validBefore: validBefore.toString(),
|
|
30858
|
+
nonce
|
|
30859
|
+
};
|
|
30860
|
+
const domain = {
|
|
30861
|
+
name: "USD Coin",
|
|
30862
|
+
version: "2",
|
|
30863
|
+
chainId: chain2.chainId,
|
|
30864
|
+
verifyingContract: chain2.usdc
|
|
30865
|
+
};
|
|
30866
|
+
const types = {
|
|
30867
|
+
TransferWithAuthorization: [
|
|
30868
|
+
{ name: "from", type: "address" },
|
|
30869
|
+
{ name: "to", type: "address" },
|
|
30870
|
+
{ name: "value", type: "uint256" },
|
|
30871
|
+
{ name: "validAfter", type: "uint256" },
|
|
30872
|
+
{ name: "validBefore", type: "uint256" },
|
|
30873
|
+
{ name: "nonce", type: "bytes32" }
|
|
30874
|
+
]
|
|
30875
|
+
};
|
|
30876
|
+
const signature = await this.wallet.signTypedData(domain, types, authorization);
|
|
30877
|
+
return { authorization, signature };
|
|
30878
|
+
}
|
|
30919
30879
|
/**
|
|
30920
30880
|
* Check spending limits
|
|
30921
30881
|
*/
|
|
@@ -30942,36 +30902,6 @@ var MoltsPayClient = class {
|
|
|
30942
30902
|
recordSpending(amount) {
|
|
30943
30903
|
this.todaySpending += amount;
|
|
30944
30904
|
}
|
|
30945
|
-
/**
|
|
30946
|
-
* Execute payment on-chain
|
|
30947
|
-
*/
|
|
30948
|
-
async executePayment(payment) {
|
|
30949
|
-
let chain2;
|
|
30950
|
-
try {
|
|
30951
|
-
chain2 = getChain(payment.chain);
|
|
30952
|
-
} catch {
|
|
30953
|
-
throw new Error(`Unknown chain: ${payment.chain}`);
|
|
30954
|
-
}
|
|
30955
|
-
const { ethers: ethers4 } = await import("ethers");
|
|
30956
|
-
const provider = new ethers4.JsonRpcProvider(chain2.rpc);
|
|
30957
|
-
const signer = new ethers4.Wallet(this.walletData.privateKey, provider);
|
|
30958
|
-
const usdcAddress = chain2.usdc;
|
|
30959
|
-
const usdcAbi = [
|
|
30960
|
-
"function transfer(address to, uint256 amount) returns (bool)",
|
|
30961
|
-
"function balanceOf(address account) view returns (uint256)"
|
|
30962
|
-
];
|
|
30963
|
-
const usdc = new ethers4.Contract(usdcAddress, usdcAbi, signer);
|
|
30964
|
-
const amountInUnits = ethers4.parseUnits(payment.amount.toString(), 6);
|
|
30965
|
-
const balance = await usdc.balanceOf(this.wallet.address);
|
|
30966
|
-
if (balance < amountInUnits) {
|
|
30967
|
-
throw new Error(
|
|
30968
|
-
`Insufficient USDC balance: ${ethers4.formatUnits(balance, 6)} < ${payment.amount}`
|
|
30969
|
-
);
|
|
30970
|
-
}
|
|
30971
|
-
const tx = await usdc.transfer(payment.wallet, amountInUnits);
|
|
30972
|
-
const receipt = await tx.wait();
|
|
30973
|
-
return receipt.hash;
|
|
30974
|
-
}
|
|
30975
30905
|
// --- Config & Wallet Management ---
|
|
30976
30906
|
loadConfig() {
|
|
30977
30907
|
const configPath = join(this.configDir, "config.json");
|
|
@@ -31031,15 +30961,14 @@ var MoltsPayClient = class {
|
|
|
31031
30961
|
} catch {
|
|
31032
30962
|
throw new Error(`Unknown chain: ${this.config.chain}`);
|
|
31033
30963
|
}
|
|
31034
|
-
const
|
|
31035
|
-
const provider = new ethers4.JsonRpcProvider(chain2.rpc);
|
|
30964
|
+
const provider = new ethers2.JsonRpcProvider(chain2.rpc);
|
|
31036
30965
|
const nativeBalance = await provider.getBalance(this.wallet.address);
|
|
31037
30966
|
const usdcAbi = ["function balanceOf(address) view returns (uint256)"];
|
|
31038
|
-
const usdc = new
|
|
30967
|
+
const usdc = new ethers2.Contract(chain2.usdc, usdcAbi, provider);
|
|
31039
30968
|
const usdcBalance = await usdc.balanceOf(this.wallet.address);
|
|
31040
30969
|
return {
|
|
31041
|
-
usdc: parseFloat(
|
|
31042
|
-
native: parseFloat(
|
|
30970
|
+
usdc: parseFloat(ethers2.formatUnits(usdcBalance, 6)),
|
|
30971
|
+
native: parseFloat(ethers2.formatEther(nativeBalance))
|
|
31043
30972
|
};
|
|
31044
30973
|
}
|
|
31045
30974
|
};
|
|
@@ -31049,11 +30978,11 @@ init_esm_shims();
|
|
|
31049
30978
|
|
|
31050
30979
|
// src/wallet/Wallet.ts
|
|
31051
30980
|
init_esm_shims();
|
|
31052
|
-
import { ethers as
|
|
30981
|
+
import { ethers as ethers3 } from "ethers";
|
|
31053
30982
|
|
|
31054
30983
|
// src/wallet/createWallet.ts
|
|
31055
30984
|
init_esm_shims();
|
|
31056
|
-
import { ethers as
|
|
30985
|
+
import { ethers as ethers4 } from "ethers";
|
|
31057
30986
|
import { writeFileSync as writeFileSync2, readFileSync as readFileSync3, existsSync as existsSync2, mkdirSync as mkdirSync2 } from "fs";
|
|
31058
30987
|
import { join as join2, dirname } from "path";
|
|
31059
30988
|
import { createCipheriv, createDecipheriv, randomBytes, scryptSync } from "crypto";
|
|
@@ -31098,7 +31027,7 @@ function createWallet(options = {}) {
|
|
|
31098
31027
|
}
|
|
31099
31028
|
}
|
|
31100
31029
|
try {
|
|
31101
|
-
const wallet =
|
|
31030
|
+
const wallet = ethers4.Wallet.createRandom();
|
|
31102
31031
|
const walletData = {
|
|
31103
31032
|
address: wallet.address,
|
|
31104
31033
|
label: options.label,
|
|
@@ -31169,6 +31098,143 @@ function walletExists(storagePath) {
|
|
|
31169
31098
|
return existsSync2(path3);
|
|
31170
31099
|
}
|
|
31171
31100
|
|
|
31101
|
+
// src/verify/index.ts
|
|
31102
|
+
init_esm_shims();
|
|
31103
|
+
import { ethers as ethers5 } from "ethers";
|
|
31104
|
+
var TRANSFER_EVENT_TOPIC = ethers5.id("Transfer(address,address,uint256)");
|
|
31105
|
+
async function verifyPayment(params) {
|
|
31106
|
+
const { txHash, expectedAmount, expectedTo } = params;
|
|
31107
|
+
let chain2;
|
|
31108
|
+
try {
|
|
31109
|
+
if (typeof params.chain === "number") {
|
|
31110
|
+
chain2 = getChainById(params.chain);
|
|
31111
|
+
} else {
|
|
31112
|
+
chain2 = getChain(params.chain || "base");
|
|
31113
|
+
}
|
|
31114
|
+
if (!chain2) {
|
|
31115
|
+
return { verified: false, error: `Unsupported chain: ${params.chain}` };
|
|
31116
|
+
}
|
|
31117
|
+
} catch (e) {
|
|
31118
|
+
return { verified: false, error: `Unsupported chain: ${params.chain}` };
|
|
31119
|
+
}
|
|
31120
|
+
try {
|
|
31121
|
+
const provider = new ethers5.JsonRpcProvider(chain2.rpc);
|
|
31122
|
+
const receipt = await provider.getTransactionReceipt(txHash);
|
|
31123
|
+
if (!receipt) {
|
|
31124
|
+
return { verified: false, error: "Transaction not found or not confirmed" };
|
|
31125
|
+
}
|
|
31126
|
+
if (receipt.status !== 1) {
|
|
31127
|
+
return { verified: false, error: "Transaction failed" };
|
|
31128
|
+
}
|
|
31129
|
+
const usdcAddress = chain2.usdc?.toLowerCase();
|
|
31130
|
+
if (!usdcAddress) {
|
|
31131
|
+
return { verified: false, error: `Chain ${chain2.name} USDC address not configured` };
|
|
31132
|
+
}
|
|
31133
|
+
for (const log of receipt.logs) {
|
|
31134
|
+
if (log.address.toLowerCase() !== usdcAddress) {
|
|
31135
|
+
continue;
|
|
31136
|
+
}
|
|
31137
|
+
if (log.topics.length < 3 || log.topics[0] !== TRANSFER_EVENT_TOPIC) {
|
|
31138
|
+
continue;
|
|
31139
|
+
}
|
|
31140
|
+
const from = "0x" + log.topics[1].slice(-40);
|
|
31141
|
+
const to = "0x" + log.topics[2].slice(-40);
|
|
31142
|
+
const amountRaw = BigInt(log.data);
|
|
31143
|
+
const amount = Number(amountRaw) / 1e6;
|
|
31144
|
+
if (expectedTo && to.toLowerCase() !== expectedTo.toLowerCase()) {
|
|
31145
|
+
continue;
|
|
31146
|
+
}
|
|
31147
|
+
if (amount < expectedAmount) {
|
|
31148
|
+
return {
|
|
31149
|
+
verified: false,
|
|
31150
|
+
error: `Insufficient amount: received ${amount} USDC, expected ${expectedAmount} USDC`,
|
|
31151
|
+
amount,
|
|
31152
|
+
from,
|
|
31153
|
+
to,
|
|
31154
|
+
txHash,
|
|
31155
|
+
blockNumber: receipt.blockNumber
|
|
31156
|
+
};
|
|
31157
|
+
}
|
|
31158
|
+
return {
|
|
31159
|
+
verified: true,
|
|
31160
|
+
amount,
|
|
31161
|
+
from,
|
|
31162
|
+
to,
|
|
31163
|
+
txHash,
|
|
31164
|
+
blockNumber: receipt.blockNumber
|
|
31165
|
+
};
|
|
31166
|
+
}
|
|
31167
|
+
return { verified: false, error: "No USDC transfer found" };
|
|
31168
|
+
} catch (e) {
|
|
31169
|
+
return { verified: false, error: e.message || String(e) };
|
|
31170
|
+
}
|
|
31171
|
+
}
|
|
31172
|
+
async function getTransactionStatus(txHash, chain2 = "base") {
|
|
31173
|
+
let chainConfig;
|
|
31174
|
+
try {
|
|
31175
|
+
chainConfig = typeof chain2 === "number" ? getChainById(chain2) : getChain(chain2);
|
|
31176
|
+
if (!chainConfig) return { status: "not_found" };
|
|
31177
|
+
} catch {
|
|
31178
|
+
return { status: "not_found" };
|
|
31179
|
+
}
|
|
31180
|
+
try {
|
|
31181
|
+
const provider = new ethers5.JsonRpcProvider(chainConfig.rpc);
|
|
31182
|
+
const receipt = await provider.getTransactionReceipt(txHash);
|
|
31183
|
+
if (!receipt) {
|
|
31184
|
+
const tx = await provider.getTransaction(txHash);
|
|
31185
|
+
if (tx) {
|
|
31186
|
+
return { status: "pending" };
|
|
31187
|
+
}
|
|
31188
|
+
return { status: "not_found" };
|
|
31189
|
+
}
|
|
31190
|
+
const currentBlock = await provider.getBlockNumber();
|
|
31191
|
+
const confirmations = currentBlock - receipt.blockNumber;
|
|
31192
|
+
if (receipt.status === 1) {
|
|
31193
|
+
return {
|
|
31194
|
+
status: "confirmed",
|
|
31195
|
+
blockNumber: receipt.blockNumber,
|
|
31196
|
+
confirmations
|
|
31197
|
+
};
|
|
31198
|
+
} else {
|
|
31199
|
+
return {
|
|
31200
|
+
status: "failed",
|
|
31201
|
+
blockNumber: receipt.blockNumber
|
|
31202
|
+
};
|
|
31203
|
+
}
|
|
31204
|
+
} catch {
|
|
31205
|
+
return { status: "not_found" };
|
|
31206
|
+
}
|
|
31207
|
+
}
|
|
31208
|
+
async function waitForTransaction(txHash, chain2 = "base", confirmations = 1, timeoutMs = 6e4) {
|
|
31209
|
+
let chainConfig;
|
|
31210
|
+
try {
|
|
31211
|
+
chainConfig = typeof chain2 === "number" ? getChainById(chain2) : getChain(chain2);
|
|
31212
|
+
if (!chainConfig) {
|
|
31213
|
+
return { verified: false, confirmed: false, error: `Unsupported chain: ${chain2}` };
|
|
31214
|
+
}
|
|
31215
|
+
} catch (e) {
|
|
31216
|
+
return { verified: false, confirmed: false, error: `Unsupported chain: ${chain2}` };
|
|
31217
|
+
}
|
|
31218
|
+
const provider = new ethers5.JsonRpcProvider(chainConfig.rpc);
|
|
31219
|
+
try {
|
|
31220
|
+
const receipt = await provider.waitForTransaction(txHash, confirmations, timeoutMs);
|
|
31221
|
+
if (!receipt) {
|
|
31222
|
+
return { verified: false, confirmed: false, error: "Timeout waiting" };
|
|
31223
|
+
}
|
|
31224
|
+
if (receipt.status !== 1) {
|
|
31225
|
+
return { verified: false, confirmed: true, error: "Transaction failed" };
|
|
31226
|
+
}
|
|
31227
|
+
return {
|
|
31228
|
+
verified: true,
|
|
31229
|
+
confirmed: true,
|
|
31230
|
+
txHash,
|
|
31231
|
+
blockNumber: receipt.blockNumber
|
|
31232
|
+
};
|
|
31233
|
+
} catch (e) {
|
|
31234
|
+
return { verified: false, confirmed: false, error: e.message || String(e) };
|
|
31235
|
+
}
|
|
31236
|
+
}
|
|
31237
|
+
|
|
31172
31238
|
// src/cdp/index.ts
|
|
31173
31239
|
init_esm_shims();
|
|
31174
31240
|
import * as fs from "fs";
|
|
@@ -31290,9 +31356,9 @@ var CDPWallet = class {
|
|
|
31290
31356
|
* Get USDC balance
|
|
31291
31357
|
*/
|
|
31292
31358
|
async getBalance() {
|
|
31293
|
-
const { ethers:
|
|
31294
|
-
const provider = new
|
|
31295
|
-
const usdcContract = new
|
|
31359
|
+
const { ethers: ethers6 } = await import("ethers");
|
|
31360
|
+
const provider = new ethers6.JsonRpcProvider(this.chainConfig.rpc);
|
|
31361
|
+
const usdcContract = new ethers6.Contract(
|
|
31296
31362
|
this.chainConfig.usdc,
|
|
31297
31363
|
["function balanceOf(address) view returns (uint256)"],
|
|
31298
31364
|
provider
|
|
@@ -31303,7 +31369,7 @@ var CDPWallet = class {
|
|
|
31303
31369
|
]);
|
|
31304
31370
|
return {
|
|
31305
31371
|
usdc: (Number(usdcBalance) / 1e6).toFixed(2),
|
|
31306
|
-
eth:
|
|
31372
|
+
eth: ethers6.formatEther(ethBalance)
|
|
31307
31373
|
};
|
|
31308
31374
|
}
|
|
31309
31375
|
/**
|
|
@@ -31321,7 +31387,7 @@ var CDPWallet = class {
|
|
|
31321
31387
|
}
|
|
31322
31388
|
try {
|
|
31323
31389
|
const { CdpClient } = await import("@coinbase/cdp-sdk");
|
|
31324
|
-
const { ethers:
|
|
31390
|
+
const { ethers: ethers6 } = await import("ethers");
|
|
31325
31391
|
const cdp = new CdpClient({
|
|
31326
31392
|
apiKeyId: creds.apiKeyId,
|
|
31327
31393
|
apiKeySecret: creds.apiKeySecret,
|
|
@@ -31329,7 +31395,7 @@ var CDPWallet = class {
|
|
|
31329
31395
|
});
|
|
31330
31396
|
const account = await cdp.evm.getAccount({ address: this.address });
|
|
31331
31397
|
const amountWei = BigInt(Math.floor(params.amount * 1e6));
|
|
31332
|
-
const iface = new
|
|
31398
|
+
const iface = new ethers6.Interface([
|
|
31333
31399
|
"function transfer(address to, uint256 amount) returns (bool)"
|
|
31334
31400
|
]);
|
|
31335
31401
|
const callData = iface.encodeFunctionData("transfer", [params.to, amountWei]);
|