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.js
CHANGED
|
@@ -30369,9 +30369,6 @@ init_cjs_shims();
|
|
|
30369
30369
|
init_cjs_shims();
|
|
30370
30370
|
var import_fs = require("fs");
|
|
30371
30371
|
var import_http = require("http");
|
|
30372
|
-
|
|
30373
|
-
// src/verify/index.ts
|
|
30374
|
-
init_cjs_shims();
|
|
30375
30372
|
var import_ethers = require("ethers");
|
|
30376
30373
|
|
|
30377
30374
|
// src/chains/index.ts
|
|
@@ -30452,165 +30449,41 @@ var ERC20_ABI = [
|
|
|
30452
30449
|
"event Approval(address indexed owner, address indexed spender, uint256 value)"
|
|
30453
30450
|
];
|
|
30454
30451
|
|
|
30455
|
-
// src/verify/index.ts
|
|
30456
|
-
var TRANSFER_EVENT_TOPIC = import_ethers.ethers.id("Transfer(address,address,uint256)");
|
|
30457
|
-
async function verifyPayment(params) {
|
|
30458
|
-
const { txHash, expectedAmount, expectedTo } = params;
|
|
30459
|
-
let chain2;
|
|
30460
|
-
try {
|
|
30461
|
-
if (typeof params.chain === "number") {
|
|
30462
|
-
chain2 = getChainById(params.chain);
|
|
30463
|
-
} else {
|
|
30464
|
-
chain2 = getChain(params.chain || "base");
|
|
30465
|
-
}
|
|
30466
|
-
if (!chain2) {
|
|
30467
|
-
return { verified: false, error: `Unsupported chain: ${params.chain}` };
|
|
30468
|
-
}
|
|
30469
|
-
} catch (e) {
|
|
30470
|
-
return { verified: false, error: `Unsupported chain: ${params.chain}` };
|
|
30471
|
-
}
|
|
30472
|
-
try {
|
|
30473
|
-
const provider = new import_ethers.ethers.JsonRpcProvider(chain2.rpc);
|
|
30474
|
-
const receipt = await provider.getTransactionReceipt(txHash);
|
|
30475
|
-
if (!receipt) {
|
|
30476
|
-
return { verified: false, error: "Transaction not found or not confirmed" };
|
|
30477
|
-
}
|
|
30478
|
-
if (receipt.status !== 1) {
|
|
30479
|
-
return { verified: false, error: "Transaction failed" };
|
|
30480
|
-
}
|
|
30481
|
-
const usdcAddress = chain2.usdc?.toLowerCase();
|
|
30482
|
-
if (!usdcAddress) {
|
|
30483
|
-
return { verified: false, error: `Chain ${chain2.name} USDC address not configured` };
|
|
30484
|
-
}
|
|
30485
|
-
for (const log of receipt.logs) {
|
|
30486
|
-
if (log.address.toLowerCase() !== usdcAddress) {
|
|
30487
|
-
continue;
|
|
30488
|
-
}
|
|
30489
|
-
if (log.topics.length < 3 || log.topics[0] !== TRANSFER_EVENT_TOPIC) {
|
|
30490
|
-
continue;
|
|
30491
|
-
}
|
|
30492
|
-
const from = "0x" + log.topics[1].slice(-40);
|
|
30493
|
-
const to = "0x" + log.topics[2].slice(-40);
|
|
30494
|
-
const amountRaw = BigInt(log.data);
|
|
30495
|
-
const amount = Number(amountRaw) / 1e6;
|
|
30496
|
-
if (expectedTo && to.toLowerCase() !== expectedTo.toLowerCase()) {
|
|
30497
|
-
continue;
|
|
30498
|
-
}
|
|
30499
|
-
if (amount < expectedAmount) {
|
|
30500
|
-
return {
|
|
30501
|
-
verified: false,
|
|
30502
|
-
error: `Insufficient amount: received ${amount} USDC, expected ${expectedAmount} USDC`,
|
|
30503
|
-
amount,
|
|
30504
|
-
from,
|
|
30505
|
-
to,
|
|
30506
|
-
txHash,
|
|
30507
|
-
blockNumber: receipt.blockNumber
|
|
30508
|
-
};
|
|
30509
|
-
}
|
|
30510
|
-
return {
|
|
30511
|
-
verified: true,
|
|
30512
|
-
amount,
|
|
30513
|
-
from,
|
|
30514
|
-
to,
|
|
30515
|
-
txHash,
|
|
30516
|
-
blockNumber: receipt.blockNumber
|
|
30517
|
-
};
|
|
30518
|
-
}
|
|
30519
|
-
return { verified: false, error: "No USDC transfer found" };
|
|
30520
|
-
} catch (e) {
|
|
30521
|
-
return { verified: false, error: e.message || String(e) };
|
|
30522
|
-
}
|
|
30523
|
-
}
|
|
30524
|
-
async function getTransactionStatus(txHash, chain2 = "base") {
|
|
30525
|
-
let chainConfig;
|
|
30526
|
-
try {
|
|
30527
|
-
chainConfig = typeof chain2 === "number" ? getChainById(chain2) : getChain(chain2);
|
|
30528
|
-
if (!chainConfig) return { status: "not_found" };
|
|
30529
|
-
} catch {
|
|
30530
|
-
return { status: "not_found" };
|
|
30531
|
-
}
|
|
30532
|
-
try {
|
|
30533
|
-
const provider = new import_ethers.ethers.JsonRpcProvider(chainConfig.rpc);
|
|
30534
|
-
const receipt = await provider.getTransactionReceipt(txHash);
|
|
30535
|
-
if (!receipt) {
|
|
30536
|
-
const tx = await provider.getTransaction(txHash);
|
|
30537
|
-
if (tx) {
|
|
30538
|
-
return { status: "pending" };
|
|
30539
|
-
}
|
|
30540
|
-
return { status: "not_found" };
|
|
30541
|
-
}
|
|
30542
|
-
const currentBlock = await provider.getBlockNumber();
|
|
30543
|
-
const confirmations = currentBlock - receipt.blockNumber;
|
|
30544
|
-
if (receipt.status === 1) {
|
|
30545
|
-
return {
|
|
30546
|
-
status: "confirmed",
|
|
30547
|
-
blockNumber: receipt.blockNumber,
|
|
30548
|
-
confirmations
|
|
30549
|
-
};
|
|
30550
|
-
} else {
|
|
30551
|
-
return {
|
|
30552
|
-
status: "failed",
|
|
30553
|
-
blockNumber: receipt.blockNumber
|
|
30554
|
-
};
|
|
30555
|
-
}
|
|
30556
|
-
} catch {
|
|
30557
|
-
return { status: "not_found" };
|
|
30558
|
-
}
|
|
30559
|
-
}
|
|
30560
|
-
async function waitForTransaction(txHash, chain2 = "base", confirmations = 1, timeoutMs = 6e4) {
|
|
30561
|
-
let chainConfig;
|
|
30562
|
-
try {
|
|
30563
|
-
chainConfig = typeof chain2 === "number" ? getChainById(chain2) : getChain(chain2);
|
|
30564
|
-
if (!chainConfig) {
|
|
30565
|
-
return { verified: false, confirmed: false, error: `Unsupported chain: ${chain2}` };
|
|
30566
|
-
}
|
|
30567
|
-
} catch (e) {
|
|
30568
|
-
return { verified: false, confirmed: false, error: `Unsupported chain: ${chain2}` };
|
|
30569
|
-
}
|
|
30570
|
-
const provider = new import_ethers.ethers.JsonRpcProvider(chainConfig.rpc);
|
|
30571
|
-
try {
|
|
30572
|
-
const receipt = await provider.waitForTransaction(txHash, confirmations, timeoutMs);
|
|
30573
|
-
if (!receipt) {
|
|
30574
|
-
return { verified: false, confirmed: false, error: "Timeout waiting" };
|
|
30575
|
-
}
|
|
30576
|
-
if (receipt.status !== 1) {
|
|
30577
|
-
return { verified: false, confirmed: true, error: "Transaction failed" };
|
|
30578
|
-
}
|
|
30579
|
-
return {
|
|
30580
|
-
verified: true,
|
|
30581
|
-
confirmed: true,
|
|
30582
|
-
txHash,
|
|
30583
|
-
blockNumber: receipt.blockNumber
|
|
30584
|
-
};
|
|
30585
|
-
} catch (e) {
|
|
30586
|
-
return { verified: false, confirmed: false, error: e.message || String(e) };
|
|
30587
|
-
}
|
|
30588
|
-
}
|
|
30589
|
-
|
|
30590
30452
|
// src/server/types.ts
|
|
30591
30453
|
init_cjs_shims();
|
|
30592
30454
|
|
|
30593
30455
|
// src/server/index.ts
|
|
30594
|
-
|
|
30595
|
-
|
|
30596
|
-
|
|
30456
|
+
var X402_VERSION = 2;
|
|
30457
|
+
var PAYMENT_REQUIRED_HEADER = "x-payment-required";
|
|
30458
|
+
var PAYMENT_HEADER = "x-payment";
|
|
30597
30459
|
var MoltsPayServer = class {
|
|
30598
30460
|
manifest;
|
|
30599
30461
|
skills = /* @__PURE__ */ new Map();
|
|
30600
|
-
charges = /* @__PURE__ */ new Map();
|
|
30601
30462
|
options;
|
|
30463
|
+
provider = null;
|
|
30464
|
+
wallet = null;
|
|
30602
30465
|
constructor(servicesPath, options = {}) {
|
|
30603
30466
|
const content = (0, import_fs.readFileSync)(servicesPath, "utf-8");
|
|
30604
30467
|
this.manifest = JSON.parse(content);
|
|
30605
30468
|
this.options = {
|
|
30606
30469
|
port: options.port || 3e3,
|
|
30607
30470
|
host: options.host || "0.0.0.0",
|
|
30608
|
-
|
|
30609
|
-
// 5 minutes
|
|
30471
|
+
privateKey: options.privateKey || process.env.MOLTSPAY_PRIVATE_KEY
|
|
30610
30472
|
};
|
|
30473
|
+
if (this.options.privateKey) {
|
|
30474
|
+
try {
|
|
30475
|
+
const chain2 = getChain(this.manifest.provider.chain);
|
|
30476
|
+
this.provider = new import_ethers.ethers.JsonRpcProvider(chain2.rpc);
|
|
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");
|
|
30481
|
+
}
|
|
30482
|
+
}
|
|
30611
30483
|
console.log(`[MoltsPay] Loaded ${this.manifest.services.length} services from ${servicesPath}`);
|
|
30612
30484
|
console.log(`[MoltsPay] Provider: ${this.manifest.provider.name}`);
|
|
30613
|
-
console.log(`[MoltsPay]
|
|
30485
|
+
console.log(`[MoltsPay] Receive wallet: ${this.manifest.provider.wallet}`);
|
|
30486
|
+
console.log(`[MoltsPay] Protocol: x402 (gasless, pay-for-success)`);
|
|
30614
30487
|
}
|
|
30615
30488
|
/**
|
|
30616
30489
|
* Register a skill handler for a service
|
|
@@ -30637,10 +30510,8 @@ var MoltsPayServer = class {
|
|
|
30637
30510
|
server.listen(p, this.options.host, () => {
|
|
30638
30511
|
console.log(`[MoltsPay] Server listening on http://${this.options.host}:${p}`);
|
|
30639
30512
|
console.log(`[MoltsPay] Endpoints:`);
|
|
30640
|
-
console.log(` GET /services
|
|
30641
|
-
console.log(` POST /
|
|
30642
|
-
console.log(` POST /verify - Verify payment & get result`);
|
|
30643
|
-
console.log(` GET /status/:id - Check charge status`);
|
|
30513
|
+
console.log(` GET /services - List available services`);
|
|
30514
|
+
console.log(` POST /execute - Execute service (x402 payment)`);
|
|
30644
30515
|
});
|
|
30645
30516
|
}
|
|
30646
30517
|
async handleRequest(req, res) {
|
|
@@ -30649,7 +30520,8 @@ var MoltsPayServer = class {
|
|
|
30649
30520
|
const method = req.method || "GET";
|
|
30650
30521
|
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
30651
30522
|
res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
|
30652
|
-
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
|
|
30523
|
+
res.setHeader("Access-Control-Allow-Headers", "Content-Type, X-Payment");
|
|
30524
|
+
res.setHeader("Access-Control-Expose-Headers", "X-Payment-Required, X-Payment-Response");
|
|
30653
30525
|
if (method === "OPTIONS") {
|
|
30654
30526
|
res.writeHead(204);
|
|
30655
30527
|
res.end();
|
|
@@ -30659,17 +30531,10 @@ var MoltsPayServer = class {
|
|
|
30659
30531
|
if (method === "GET" && path2 === "/services") {
|
|
30660
30532
|
return this.handleGetServices(res);
|
|
30661
30533
|
}
|
|
30662
|
-
if (method === "POST" && path2 === "/
|
|
30663
|
-
const body = await this.readBody(req);
|
|
30664
|
-
return this.handlePay(body, res);
|
|
30665
|
-
}
|
|
30666
|
-
if (method === "POST" && path2 === "/verify") {
|
|
30534
|
+
if (method === "POST" && path2 === "/execute") {
|
|
30667
30535
|
const body = await this.readBody(req);
|
|
30668
|
-
|
|
30669
|
-
|
|
30670
|
-
if (method === "GET" && path2.startsWith("/status/")) {
|
|
30671
|
-
const chargeId = path2.replace("/status/", "");
|
|
30672
|
-
return this.handleStatus(chargeId, res);
|
|
30536
|
+
const paymentHeader = req.headers[PAYMENT_HEADER];
|
|
30537
|
+
return this.handleExecute(body, paymentHeader, res);
|
|
30673
30538
|
}
|
|
30674
30539
|
this.sendJson(res, 404, { error: "Not found" });
|
|
30675
30540
|
} catch (err) {
|
|
@@ -30681,6 +30546,7 @@ var MoltsPayServer = class {
|
|
|
30681
30546
|
* GET /services - List available services
|
|
30682
30547
|
*/
|
|
30683
30548
|
handleGetServices(res) {
|
|
30549
|
+
const chain2 = getChain(this.manifest.provider.chain);
|
|
30684
30550
|
const services = this.manifest.services.map((s) => ({
|
|
30685
30551
|
id: s.id,
|
|
30686
30552
|
name: s.name,
|
|
@@ -30693,14 +30559,20 @@ var MoltsPayServer = class {
|
|
|
30693
30559
|
}));
|
|
30694
30560
|
this.sendJson(res, 200, {
|
|
30695
30561
|
provider: this.manifest.provider,
|
|
30696
|
-
services
|
|
30562
|
+
services,
|
|
30563
|
+
x402: {
|
|
30564
|
+
version: X402_VERSION,
|
|
30565
|
+
network: `eip155:${chain2.chainId}`,
|
|
30566
|
+
schemes: ["exact"]
|
|
30567
|
+
}
|
|
30697
30568
|
});
|
|
30698
30569
|
}
|
|
30699
30570
|
/**
|
|
30700
|
-
* POST /
|
|
30571
|
+
* POST /execute - Execute service with x402 payment
|
|
30701
30572
|
* Body: { service: string, params: object }
|
|
30573
|
+
* Header: X-Payment (optional - if missing, returns 402)
|
|
30702
30574
|
*/
|
|
30703
|
-
|
|
30575
|
+
async handleExecute(body, paymentHeader, res) {
|
|
30704
30576
|
const { service, params } = body;
|
|
30705
30577
|
if (!service) {
|
|
30706
30578
|
return this.sendJson(res, 400, { error: "Missing service" });
|
|
@@ -30714,113 +30586,129 @@ var MoltsPayServer = class {
|
|
|
30714
30586
|
return this.sendJson(res, 400, { error: `Missing required param: ${key}` });
|
|
30715
30587
|
}
|
|
30716
30588
|
}
|
|
30717
|
-
|
|
30718
|
-
|
|
30719
|
-
|
|
30720
|
-
|
|
30721
|
-
|
|
30722
|
-
|
|
30723
|
-
|
|
30724
|
-
|
|
30725
|
-
|
|
30726
|
-
|
|
30727
|
-
|
|
30728
|
-
|
|
30729
|
-
|
|
30730
|
-
|
|
30731
|
-
|
|
30732
|
-
|
|
30733
|
-
|
|
30734
|
-
|
|
30735
|
-
|
|
30736
|
-
|
|
30737
|
-
|
|
30738
|
-
|
|
30739
|
-
|
|
30740
|
-
|
|
30741
|
-
|
|
30589
|
+
if (!paymentHeader) {
|
|
30590
|
+
return this.sendPaymentRequired(skill.config, res);
|
|
30591
|
+
}
|
|
30592
|
+
let payment;
|
|
30593
|
+
try {
|
|
30594
|
+
const decoded = Buffer.from(paymentHeader, "base64").toString("utf-8");
|
|
30595
|
+
payment = JSON.parse(decoded);
|
|
30596
|
+
} catch {
|
|
30597
|
+
return this.sendJson(res, 400, { error: "Invalid X-Payment header" });
|
|
30598
|
+
}
|
|
30599
|
+
const validation = this.validatePayment(payment, skill.config);
|
|
30600
|
+
if (!validation.valid) {
|
|
30601
|
+
return this.sendJson(res, 402, { error: validation.error });
|
|
30602
|
+
}
|
|
30603
|
+
console.log(`[MoltsPay] Executing skill: ${service}`);
|
|
30604
|
+
let result;
|
|
30605
|
+
try {
|
|
30606
|
+
result = await skill.handler(params || {});
|
|
30607
|
+
} catch (err) {
|
|
30608
|
+
console.error("[MoltsPay] Skill execution failed:", err.message);
|
|
30609
|
+
return this.sendJson(res, 500, {
|
|
30610
|
+
error: "Service execution failed",
|
|
30611
|
+
message: err.message
|
|
30612
|
+
});
|
|
30613
|
+
}
|
|
30614
|
+
console.log(`[MoltsPay] Skill succeeded, claiming payment...`);
|
|
30615
|
+
let txHash = null;
|
|
30616
|
+
try {
|
|
30617
|
+
txHash = await this.claimPayment(payment);
|
|
30618
|
+
console.log(`[MoltsPay] Payment claimed: ${txHash}`);
|
|
30619
|
+
} catch (err) {
|
|
30620
|
+
console.error("[MoltsPay] Payment claim failed:", err.message);
|
|
30621
|
+
}
|
|
30622
|
+
this.sendJson(res, 200, {
|
|
30623
|
+
success: true,
|
|
30624
|
+
result,
|
|
30625
|
+
payment: txHash ? { txHash, status: "claimed" } : { status: "pending" }
|
|
30742
30626
|
});
|
|
30743
30627
|
}
|
|
30744
30628
|
/**
|
|
30745
|
-
*
|
|
30746
|
-
* Body: { chargeId: string, txHash: string }
|
|
30629
|
+
* Return 402 with x402 payment requirements
|
|
30747
30630
|
*/
|
|
30748
|
-
|
|
30749
|
-
const
|
|
30750
|
-
|
|
30751
|
-
|
|
30631
|
+
sendPaymentRequired(config, res) {
|
|
30632
|
+
const chain2 = getChain(this.manifest.provider.chain);
|
|
30633
|
+
const amountInUnits = Math.floor(config.price * 1e6).toString();
|
|
30634
|
+
const requirements = [{
|
|
30635
|
+
scheme: "exact",
|
|
30636
|
+
network: `eip155:${chain2.chainId}`,
|
|
30637
|
+
maxAmountRequired: amountInUnits,
|
|
30638
|
+
resource: this.manifest.provider.wallet,
|
|
30639
|
+
description: `${config.name} - $${config.price} ${config.currency}`
|
|
30640
|
+
}];
|
|
30641
|
+
const encoded = Buffer.from(JSON.stringify(requirements)).toString("base64");
|
|
30642
|
+
res.writeHead(402, {
|
|
30643
|
+
"Content-Type": "application/json",
|
|
30644
|
+
[PAYMENT_REQUIRED_HEADER]: encoded
|
|
30645
|
+
});
|
|
30646
|
+
res.end(JSON.stringify({
|
|
30647
|
+
error: "Payment required",
|
|
30648
|
+
message: `Service requires $${config.price} ${config.currency}`,
|
|
30649
|
+
x402: requirements[0]
|
|
30650
|
+
}, null, 2));
|
|
30651
|
+
}
|
|
30652
|
+
/**
|
|
30653
|
+
* Validate x402 payment payload
|
|
30654
|
+
*/
|
|
30655
|
+
validatePayment(payment, config) {
|
|
30656
|
+
if (payment.x402Version !== X402_VERSION) {
|
|
30657
|
+
return { valid: false, error: `Unsupported x402 version: ${payment.x402Version}` };
|
|
30752
30658
|
}
|
|
30753
|
-
|
|
30754
|
-
|
|
30755
|
-
return this.sendJson(res, 404, { error: "Charge not found" });
|
|
30659
|
+
if (payment.scheme !== "exact") {
|
|
30660
|
+
return { valid: false, error: `Unsupported scheme: ${payment.scheme}` };
|
|
30756
30661
|
}
|
|
30757
|
-
|
|
30758
|
-
|
|
30759
|
-
|
|
30662
|
+
const chain2 = getChain(this.manifest.provider.chain);
|
|
30663
|
+
const expectedNetwork = `eip155:${chain2.chainId}`;
|
|
30664
|
+
if (payment.network !== expectedNetwork) {
|
|
30665
|
+
return { valid: false, error: `Network mismatch: expected ${expectedNetwork}` };
|
|
30760
30666
|
}
|
|
30761
|
-
|
|
30762
|
-
|
|
30763
|
-
|
|
30764
|
-
result: charge.result
|
|
30765
|
-
});
|
|
30667
|
+
const auth = payment.payload.authorization;
|
|
30668
|
+
if (auth.to.toLowerCase() !== this.manifest.provider.wallet.toLowerCase()) {
|
|
30669
|
+
return { valid: false, error: "Payment recipient mismatch" };
|
|
30766
30670
|
}
|
|
30767
|
-
|
|
30768
|
-
|
|
30769
|
-
|
|
30770
|
-
|
|
30771
|
-
|
|
30772
|
-
|
|
30773
|
-
}
|
|
30774
|
-
if (!verification.verified) {
|
|
30775
|
-
charge.status = "failed";
|
|
30776
|
-
return this.sendJson(res, 400, {
|
|
30777
|
-
error: "Payment verification failed",
|
|
30778
|
-
reason: verification.error
|
|
30779
|
-
});
|
|
30780
|
-
}
|
|
30781
|
-
charge.status = "paid";
|
|
30782
|
-
charge.txHash = txHash;
|
|
30783
|
-
charge.paidAt = Date.now();
|
|
30784
|
-
const skill = this.skills.get(charge.service);
|
|
30785
|
-
console.log(`[MoltsPay] Executing skill: ${charge.service}`);
|
|
30786
|
-
const result = await skill.handler(charge.params);
|
|
30787
|
-
charge.status = "completed";
|
|
30788
|
-
charge.result = result;
|
|
30789
|
-
charge.completedAt = Date.now();
|
|
30790
|
-
this.sendJson(res, 200, {
|
|
30791
|
-
status: "completed",
|
|
30792
|
-
chargeId,
|
|
30793
|
-
txHash,
|
|
30794
|
-
result
|
|
30795
|
-
});
|
|
30796
|
-
} catch (err) {
|
|
30797
|
-
console.error("[MoltsPay] Skill execution error:", err);
|
|
30798
|
-
charge.status = "failed";
|
|
30799
|
-
this.sendJson(res, 500, {
|
|
30800
|
-
error: "Skill execution failed",
|
|
30801
|
-
message: err.message
|
|
30802
|
-
});
|
|
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" };
|
|
30803
30678
|
}
|
|
30679
|
+
if (Number(auth.validAfter) > now) {
|
|
30680
|
+
return { valid: false, error: "Payment authorization not yet valid" };
|
|
30681
|
+
}
|
|
30682
|
+
return { valid: true };
|
|
30804
30683
|
}
|
|
30805
30684
|
/**
|
|
30806
|
-
*
|
|
30685
|
+
* Claim payment using transferWithAuthorization
|
|
30807
30686
|
*/
|
|
30808
|
-
|
|
30809
|
-
|
|
30810
|
-
|
|
30811
|
-
return this.sendJson(res, 404, { error: "Charge not found" });
|
|
30687
|
+
async claimPayment(payment) {
|
|
30688
|
+
if (!this.wallet || !this.provider) {
|
|
30689
|
+
throw new Error("Wallet not configured for payment claims");
|
|
30812
30690
|
}
|
|
30813
|
-
this.
|
|
30814
|
-
|
|
30815
|
-
|
|
30816
|
-
|
|
30817
|
-
|
|
30818
|
-
|
|
30819
|
-
|
|
30820
|
-
|
|
30821
|
-
|
|
30822
|
-
|
|
30823
|
-
|
|
30691
|
+
const chain2 = getChain(this.manifest.provider.chain);
|
|
30692
|
+
const auth = payment.payload.authorization;
|
|
30693
|
+
const sig = payment.payload.signature;
|
|
30694
|
+
const { r, s, v } = import_ethers.ethers.Signature.from(sig);
|
|
30695
|
+
const usdcAbi = [
|
|
30696
|
+
"function transferWithAuthorization(address from, address to, uint256 value, uint256 validAfter, uint256 validBefore, bytes32 nonce, uint8 v, bytes32 r, bytes32 s)"
|
|
30697
|
+
];
|
|
30698
|
+
const usdc = new import_ethers.ethers.Contract(chain2.usdc, usdcAbi, this.wallet);
|
|
30699
|
+
const tx = await usdc.transferWithAuthorization(
|
|
30700
|
+
auth.from,
|
|
30701
|
+
auth.to,
|
|
30702
|
+
auth.value,
|
|
30703
|
+
auth.validAfter,
|
|
30704
|
+
auth.validBefore,
|
|
30705
|
+
auth.nonce,
|
|
30706
|
+
v,
|
|
30707
|
+
r,
|
|
30708
|
+
s
|
|
30709
|
+
);
|
|
30710
|
+
const receipt = await tx.wait();
|
|
30711
|
+
return receipt.hash;
|
|
30824
30712
|
}
|
|
30825
30713
|
async readBody(req) {
|
|
30826
30714
|
return new Promise((resolve, reject) => {
|
|
@@ -30853,6 +30741,9 @@ var import_ethers2 = require("ethers");
|
|
|
30853
30741
|
init_cjs_shims();
|
|
30854
30742
|
|
|
30855
30743
|
// src/client/index.ts
|
|
30744
|
+
var X402_VERSION2 = 2;
|
|
30745
|
+
var PAYMENT_REQUIRED_HEADER2 = "x-payment-required";
|
|
30746
|
+
var PAYMENT_HEADER2 = "x-payment";
|
|
30856
30747
|
var DEFAULT_CONFIG = {
|
|
30857
30748
|
chain: "base",
|
|
30858
30749
|
limits: {
|
|
@@ -30916,43 +30807,112 @@ var MoltsPayClient = class {
|
|
|
30916
30807
|
return res.json();
|
|
30917
30808
|
}
|
|
30918
30809
|
/**
|
|
30919
|
-
* Pay for a service and get the result
|
|
30810
|
+
* Pay for a service and get the result (x402 protocol)
|
|
30811
|
+
*
|
|
30812
|
+
* This is GASLESS for the client - server pays gas to claim payment.
|
|
30813
|
+
* This is PAY-FOR-SUCCESS - payment only claimed if service succeeds.
|
|
30920
30814
|
*/
|
|
30921
30815
|
async pay(serverUrl, service, params) {
|
|
30922
|
-
if (!this.wallet) {
|
|
30816
|
+
if (!this.wallet || !this.walletData) {
|
|
30923
30817
|
throw new Error("Client not initialized. Run: npx moltspay init");
|
|
30924
30818
|
}
|
|
30925
|
-
|
|
30819
|
+
console.log(`[MoltsPay] Requesting service: ${service}`);
|
|
30820
|
+
const initialRes = await fetch(`${serverUrl}/execute`, {
|
|
30926
30821
|
method: "POST",
|
|
30927
30822
|
headers: { "Content-Type": "application/json" },
|
|
30928
30823
|
body: JSON.stringify({ service, params })
|
|
30929
30824
|
});
|
|
30930
|
-
if (
|
|
30931
|
-
const
|
|
30932
|
-
|
|
30825
|
+
if (initialRes.status !== 402) {
|
|
30826
|
+
const data = await initialRes.json();
|
|
30827
|
+
if (initialRes.ok && data.result) {
|
|
30828
|
+
return data.result;
|
|
30829
|
+
}
|
|
30830
|
+
throw new Error(data.error || "Unexpected response");
|
|
30933
30831
|
}
|
|
30934
|
-
const
|
|
30935
|
-
|
|
30936
|
-
|
|
30937
|
-
|
|
30938
|
-
|
|
30939
|
-
|
|
30940
|
-
|
|
30832
|
+
const paymentRequiredHeader = initialRes.headers.get(PAYMENT_REQUIRED_HEADER2);
|
|
30833
|
+
if (!paymentRequiredHeader) {
|
|
30834
|
+
throw new Error("Missing x-payment-required header");
|
|
30835
|
+
}
|
|
30836
|
+
let requirements;
|
|
30837
|
+
try {
|
|
30838
|
+
const decoded = Buffer.from(paymentRequiredHeader, "base64").toString("utf-8");
|
|
30839
|
+
requirements = JSON.parse(decoded);
|
|
30840
|
+
if (!Array.isArray(requirements)) {
|
|
30841
|
+
requirements = [requirements];
|
|
30842
|
+
}
|
|
30843
|
+
} catch {
|
|
30844
|
+
throw new Error("Invalid x-payment-required header");
|
|
30845
|
+
}
|
|
30846
|
+
const chain2 = getChain(this.config.chain);
|
|
30847
|
+
const network = `eip155:${chain2.chainId}`;
|
|
30848
|
+
const req = requirements.find((r) => r.scheme === "exact" && r.network === network);
|
|
30849
|
+
if (!req) {
|
|
30850
|
+
throw new Error(`No matching payment option for ${network}`);
|
|
30851
|
+
}
|
|
30852
|
+
const amount = Number(req.maxAmountRequired) / 1e6;
|
|
30853
|
+
this.checkLimits(amount);
|
|
30854
|
+
console.log(`[MoltsPay] Signing payment: $${amount} USDC (gasless)`);
|
|
30855
|
+
const authorization = await this.signEIP3009(req.resource, amount, chain2);
|
|
30856
|
+
const payload = {
|
|
30857
|
+
x402Version: X402_VERSION2,
|
|
30858
|
+
scheme: "exact",
|
|
30859
|
+
network,
|
|
30860
|
+
payload: authorization
|
|
30861
|
+
};
|
|
30862
|
+
const paymentHeader = Buffer.from(JSON.stringify(payload)).toString("base64");
|
|
30863
|
+
console.log(`[MoltsPay] Sending request with payment...`);
|
|
30864
|
+
const paidRes = await fetch(`${serverUrl}/execute`, {
|
|
30941
30865
|
method: "POST",
|
|
30942
|
-
headers: {
|
|
30943
|
-
|
|
30944
|
-
|
|
30945
|
-
|
|
30946
|
-
})
|
|
30866
|
+
headers: {
|
|
30867
|
+
"Content-Type": "application/json",
|
|
30868
|
+
[PAYMENT_HEADER2]: paymentHeader
|
|
30869
|
+
},
|
|
30870
|
+
body: JSON.stringify({ service, params })
|
|
30947
30871
|
});
|
|
30948
|
-
|
|
30949
|
-
|
|
30950
|
-
throw new Error(
|
|
30872
|
+
const result = await paidRes.json();
|
|
30873
|
+
if (!paidRes.ok) {
|
|
30874
|
+
throw new Error(result.error || "Service execution failed");
|
|
30951
30875
|
}
|
|
30952
|
-
|
|
30953
|
-
|
|
30876
|
+
this.recordSpending(amount);
|
|
30877
|
+
console.log(`[MoltsPay] Success! Payment: ${result.payment?.status || "claimed"}`);
|
|
30954
30878
|
return result.result;
|
|
30955
30879
|
}
|
|
30880
|
+
/**
|
|
30881
|
+
* Sign EIP-3009 transferWithAuthorization (GASLESS)
|
|
30882
|
+
* This only signs - no on-chain transaction, no gas needed.
|
|
30883
|
+
*/
|
|
30884
|
+
async signEIP3009(to, amount, chain2) {
|
|
30885
|
+
const validAfter = 0;
|
|
30886
|
+
const validBefore = Math.floor(Date.now() / 1e3) + 3600;
|
|
30887
|
+
const nonce = import_ethers2.ethers.hexlify(import_ethers2.ethers.randomBytes(32));
|
|
30888
|
+
const value = BigInt(Math.floor(amount * 1e6)).toString();
|
|
30889
|
+
const authorization = {
|
|
30890
|
+
from: this.wallet.address,
|
|
30891
|
+
to,
|
|
30892
|
+
value,
|
|
30893
|
+
validAfter: validAfter.toString(),
|
|
30894
|
+
validBefore: validBefore.toString(),
|
|
30895
|
+
nonce
|
|
30896
|
+
};
|
|
30897
|
+
const domain = {
|
|
30898
|
+
name: "USD Coin",
|
|
30899
|
+
version: "2",
|
|
30900
|
+
chainId: chain2.chainId,
|
|
30901
|
+
verifyingContract: chain2.usdc
|
|
30902
|
+
};
|
|
30903
|
+
const types = {
|
|
30904
|
+
TransferWithAuthorization: [
|
|
30905
|
+
{ name: "from", type: "address" },
|
|
30906
|
+
{ name: "to", type: "address" },
|
|
30907
|
+
{ name: "value", type: "uint256" },
|
|
30908
|
+
{ name: "validAfter", type: "uint256" },
|
|
30909
|
+
{ name: "validBefore", type: "uint256" },
|
|
30910
|
+
{ name: "nonce", type: "bytes32" }
|
|
30911
|
+
]
|
|
30912
|
+
};
|
|
30913
|
+
const signature = await this.wallet.signTypedData(domain, types, authorization);
|
|
30914
|
+
return { authorization, signature };
|
|
30915
|
+
}
|
|
30956
30916
|
/**
|
|
30957
30917
|
* Check spending limits
|
|
30958
30918
|
*/
|
|
@@ -30979,36 +30939,6 @@ var MoltsPayClient = class {
|
|
|
30979
30939
|
recordSpending(amount) {
|
|
30980
30940
|
this.todaySpending += amount;
|
|
30981
30941
|
}
|
|
30982
|
-
/**
|
|
30983
|
-
* Execute payment on-chain
|
|
30984
|
-
*/
|
|
30985
|
-
async executePayment(payment) {
|
|
30986
|
-
let chain2;
|
|
30987
|
-
try {
|
|
30988
|
-
chain2 = getChain(payment.chain);
|
|
30989
|
-
} catch {
|
|
30990
|
-
throw new Error(`Unknown chain: ${payment.chain}`);
|
|
30991
|
-
}
|
|
30992
|
-
const { ethers: ethers4 } = await import("ethers");
|
|
30993
|
-
const provider = new ethers4.JsonRpcProvider(chain2.rpc);
|
|
30994
|
-
const signer = new ethers4.Wallet(this.walletData.privateKey, provider);
|
|
30995
|
-
const usdcAddress = chain2.usdc;
|
|
30996
|
-
const usdcAbi = [
|
|
30997
|
-
"function transfer(address to, uint256 amount) returns (bool)",
|
|
30998
|
-
"function balanceOf(address account) view returns (uint256)"
|
|
30999
|
-
];
|
|
31000
|
-
const usdc = new ethers4.Contract(usdcAddress, usdcAbi, signer);
|
|
31001
|
-
const amountInUnits = ethers4.parseUnits(payment.amount.toString(), 6);
|
|
31002
|
-
const balance = await usdc.balanceOf(this.wallet.address);
|
|
31003
|
-
if (balance < amountInUnits) {
|
|
31004
|
-
throw new Error(
|
|
31005
|
-
`Insufficient USDC balance: ${ethers4.formatUnits(balance, 6)} < ${payment.amount}`
|
|
31006
|
-
);
|
|
31007
|
-
}
|
|
31008
|
-
const tx = await usdc.transfer(payment.wallet, amountInUnits);
|
|
31009
|
-
const receipt = await tx.wait();
|
|
31010
|
-
return receipt.hash;
|
|
31011
|
-
}
|
|
31012
30942
|
// --- Config & Wallet Management ---
|
|
31013
30943
|
loadConfig() {
|
|
31014
30944
|
const configPath = (0, import_path.join)(this.configDir, "config.json");
|
|
@@ -31068,15 +30998,14 @@ var MoltsPayClient = class {
|
|
|
31068
30998
|
} catch {
|
|
31069
30999
|
throw new Error(`Unknown chain: ${this.config.chain}`);
|
|
31070
31000
|
}
|
|
31071
|
-
const
|
|
31072
|
-
const provider = new ethers4.JsonRpcProvider(chain2.rpc);
|
|
31001
|
+
const provider = new import_ethers2.ethers.JsonRpcProvider(chain2.rpc);
|
|
31073
31002
|
const nativeBalance = await provider.getBalance(this.wallet.address);
|
|
31074
31003
|
const usdcAbi = ["function balanceOf(address) view returns (uint256)"];
|
|
31075
|
-
const usdc = new
|
|
31004
|
+
const usdc = new import_ethers2.ethers.Contract(chain2.usdc, usdcAbi, provider);
|
|
31076
31005
|
const usdcBalance = await usdc.balanceOf(this.wallet.address);
|
|
31077
31006
|
return {
|
|
31078
|
-
usdc: parseFloat(
|
|
31079
|
-
native: parseFloat(
|
|
31007
|
+
usdc: parseFloat(import_ethers2.ethers.formatUnits(usdcBalance, 6)),
|
|
31008
|
+
native: parseFloat(import_ethers2.ethers.formatEther(nativeBalance))
|
|
31080
31009
|
};
|
|
31081
31010
|
}
|
|
31082
31011
|
};
|
|
@@ -31206,6 +31135,143 @@ function walletExists(storagePath) {
|
|
|
31206
31135
|
return (0, import_fs3.existsSync)(path2);
|
|
31207
31136
|
}
|
|
31208
31137
|
|
|
31138
|
+
// src/verify/index.ts
|
|
31139
|
+
init_cjs_shims();
|
|
31140
|
+
var import_ethers5 = require("ethers");
|
|
31141
|
+
var TRANSFER_EVENT_TOPIC = import_ethers5.ethers.id("Transfer(address,address,uint256)");
|
|
31142
|
+
async function verifyPayment(params) {
|
|
31143
|
+
const { txHash, expectedAmount, expectedTo } = params;
|
|
31144
|
+
let chain2;
|
|
31145
|
+
try {
|
|
31146
|
+
if (typeof params.chain === "number") {
|
|
31147
|
+
chain2 = getChainById(params.chain);
|
|
31148
|
+
} else {
|
|
31149
|
+
chain2 = getChain(params.chain || "base");
|
|
31150
|
+
}
|
|
31151
|
+
if (!chain2) {
|
|
31152
|
+
return { verified: false, error: `Unsupported chain: ${params.chain}` };
|
|
31153
|
+
}
|
|
31154
|
+
} catch (e) {
|
|
31155
|
+
return { verified: false, error: `Unsupported chain: ${params.chain}` };
|
|
31156
|
+
}
|
|
31157
|
+
try {
|
|
31158
|
+
const provider = new import_ethers5.ethers.JsonRpcProvider(chain2.rpc);
|
|
31159
|
+
const receipt = await provider.getTransactionReceipt(txHash);
|
|
31160
|
+
if (!receipt) {
|
|
31161
|
+
return { verified: false, error: "Transaction not found or not confirmed" };
|
|
31162
|
+
}
|
|
31163
|
+
if (receipt.status !== 1) {
|
|
31164
|
+
return { verified: false, error: "Transaction failed" };
|
|
31165
|
+
}
|
|
31166
|
+
const usdcAddress = chain2.usdc?.toLowerCase();
|
|
31167
|
+
if (!usdcAddress) {
|
|
31168
|
+
return { verified: false, error: `Chain ${chain2.name} USDC address not configured` };
|
|
31169
|
+
}
|
|
31170
|
+
for (const log of receipt.logs) {
|
|
31171
|
+
if (log.address.toLowerCase() !== usdcAddress) {
|
|
31172
|
+
continue;
|
|
31173
|
+
}
|
|
31174
|
+
if (log.topics.length < 3 || log.topics[0] !== TRANSFER_EVENT_TOPIC) {
|
|
31175
|
+
continue;
|
|
31176
|
+
}
|
|
31177
|
+
const from = "0x" + log.topics[1].slice(-40);
|
|
31178
|
+
const to = "0x" + log.topics[2].slice(-40);
|
|
31179
|
+
const amountRaw = BigInt(log.data);
|
|
31180
|
+
const amount = Number(amountRaw) / 1e6;
|
|
31181
|
+
if (expectedTo && to.toLowerCase() !== expectedTo.toLowerCase()) {
|
|
31182
|
+
continue;
|
|
31183
|
+
}
|
|
31184
|
+
if (amount < expectedAmount) {
|
|
31185
|
+
return {
|
|
31186
|
+
verified: false,
|
|
31187
|
+
error: `Insufficient amount: received ${amount} USDC, expected ${expectedAmount} USDC`,
|
|
31188
|
+
amount,
|
|
31189
|
+
from,
|
|
31190
|
+
to,
|
|
31191
|
+
txHash,
|
|
31192
|
+
blockNumber: receipt.blockNumber
|
|
31193
|
+
};
|
|
31194
|
+
}
|
|
31195
|
+
return {
|
|
31196
|
+
verified: true,
|
|
31197
|
+
amount,
|
|
31198
|
+
from,
|
|
31199
|
+
to,
|
|
31200
|
+
txHash,
|
|
31201
|
+
blockNumber: receipt.blockNumber
|
|
31202
|
+
};
|
|
31203
|
+
}
|
|
31204
|
+
return { verified: false, error: "No USDC transfer found" };
|
|
31205
|
+
} catch (e) {
|
|
31206
|
+
return { verified: false, error: e.message || String(e) };
|
|
31207
|
+
}
|
|
31208
|
+
}
|
|
31209
|
+
async function getTransactionStatus(txHash, chain2 = "base") {
|
|
31210
|
+
let chainConfig;
|
|
31211
|
+
try {
|
|
31212
|
+
chainConfig = typeof chain2 === "number" ? getChainById(chain2) : getChain(chain2);
|
|
31213
|
+
if (!chainConfig) return { status: "not_found" };
|
|
31214
|
+
} catch {
|
|
31215
|
+
return { status: "not_found" };
|
|
31216
|
+
}
|
|
31217
|
+
try {
|
|
31218
|
+
const provider = new import_ethers5.ethers.JsonRpcProvider(chainConfig.rpc);
|
|
31219
|
+
const receipt = await provider.getTransactionReceipt(txHash);
|
|
31220
|
+
if (!receipt) {
|
|
31221
|
+
const tx = await provider.getTransaction(txHash);
|
|
31222
|
+
if (tx) {
|
|
31223
|
+
return { status: "pending" };
|
|
31224
|
+
}
|
|
31225
|
+
return { status: "not_found" };
|
|
31226
|
+
}
|
|
31227
|
+
const currentBlock = await provider.getBlockNumber();
|
|
31228
|
+
const confirmations = currentBlock - receipt.blockNumber;
|
|
31229
|
+
if (receipt.status === 1) {
|
|
31230
|
+
return {
|
|
31231
|
+
status: "confirmed",
|
|
31232
|
+
blockNumber: receipt.blockNumber,
|
|
31233
|
+
confirmations
|
|
31234
|
+
};
|
|
31235
|
+
} else {
|
|
31236
|
+
return {
|
|
31237
|
+
status: "failed",
|
|
31238
|
+
blockNumber: receipt.blockNumber
|
|
31239
|
+
};
|
|
31240
|
+
}
|
|
31241
|
+
} catch {
|
|
31242
|
+
return { status: "not_found" };
|
|
31243
|
+
}
|
|
31244
|
+
}
|
|
31245
|
+
async function waitForTransaction(txHash, chain2 = "base", confirmations = 1, timeoutMs = 6e4) {
|
|
31246
|
+
let chainConfig;
|
|
31247
|
+
try {
|
|
31248
|
+
chainConfig = typeof chain2 === "number" ? getChainById(chain2) : getChain(chain2);
|
|
31249
|
+
if (!chainConfig) {
|
|
31250
|
+
return { verified: false, confirmed: false, error: `Unsupported chain: ${chain2}` };
|
|
31251
|
+
}
|
|
31252
|
+
} catch (e) {
|
|
31253
|
+
return { verified: false, confirmed: false, error: `Unsupported chain: ${chain2}` };
|
|
31254
|
+
}
|
|
31255
|
+
const provider = new import_ethers5.ethers.JsonRpcProvider(chainConfig.rpc);
|
|
31256
|
+
try {
|
|
31257
|
+
const receipt = await provider.waitForTransaction(txHash, confirmations, timeoutMs);
|
|
31258
|
+
if (!receipt) {
|
|
31259
|
+
return { verified: false, confirmed: false, error: "Timeout waiting" };
|
|
31260
|
+
}
|
|
31261
|
+
if (receipt.status !== 1) {
|
|
31262
|
+
return { verified: false, confirmed: true, error: "Transaction failed" };
|
|
31263
|
+
}
|
|
31264
|
+
return {
|
|
31265
|
+
verified: true,
|
|
31266
|
+
confirmed: true,
|
|
31267
|
+
txHash,
|
|
31268
|
+
blockNumber: receipt.blockNumber
|
|
31269
|
+
};
|
|
31270
|
+
} catch (e) {
|
|
31271
|
+
return { verified: false, confirmed: false, error: e.message || String(e) };
|
|
31272
|
+
}
|
|
31273
|
+
}
|
|
31274
|
+
|
|
31209
31275
|
// src/cdp/index.ts
|
|
31210
31276
|
init_cjs_shims();
|
|
31211
31277
|
var fs = __toESM(require("fs"));
|
|
@@ -31327,9 +31393,9 @@ var CDPWallet = class {
|
|
|
31327
31393
|
* Get USDC balance
|
|
31328
31394
|
*/
|
|
31329
31395
|
async getBalance() {
|
|
31330
|
-
const { ethers:
|
|
31331
|
-
const provider = new
|
|
31332
|
-
const usdcContract = new
|
|
31396
|
+
const { ethers: ethers6 } = await import("ethers");
|
|
31397
|
+
const provider = new ethers6.JsonRpcProvider(this.chainConfig.rpc);
|
|
31398
|
+
const usdcContract = new ethers6.Contract(
|
|
31333
31399
|
this.chainConfig.usdc,
|
|
31334
31400
|
["function balanceOf(address) view returns (uint256)"],
|
|
31335
31401
|
provider
|
|
@@ -31340,7 +31406,7 @@ var CDPWallet = class {
|
|
|
31340
31406
|
]);
|
|
31341
31407
|
return {
|
|
31342
31408
|
usdc: (Number(usdcBalance) / 1e6).toFixed(2),
|
|
31343
|
-
eth:
|
|
31409
|
+
eth: ethers6.formatEther(ethBalance)
|
|
31344
31410
|
};
|
|
31345
31411
|
}
|
|
31346
31412
|
/**
|
|
@@ -31358,7 +31424,7 @@ var CDPWallet = class {
|
|
|
31358
31424
|
}
|
|
31359
31425
|
try {
|
|
31360
31426
|
const { CdpClient } = await import("@coinbase/cdp-sdk");
|
|
31361
|
-
const { ethers:
|
|
31427
|
+
const { ethers: ethers6 } = await import("ethers");
|
|
31362
31428
|
const cdp = new CdpClient({
|
|
31363
31429
|
apiKeyId: creds.apiKeyId,
|
|
31364
31430
|
apiKeySecret: creds.apiKeySecret,
|
|
@@ -31366,7 +31432,7 @@ var CDPWallet = class {
|
|
|
31366
31432
|
});
|
|
31367
31433
|
const account = await cdp.evm.getAccount({ address: this.address });
|
|
31368
31434
|
const amountWei = BigInt(Math.floor(params.amount * 1e6));
|
|
31369
|
-
const iface = new
|
|
31435
|
+
const iface = new ethers6.Interface([
|
|
31370
31436
|
"function transfer(address to, uint256 amount) returns (bool)"
|
|
31371
31437
|
]);
|
|
31372
31438
|
const callData = iface.encodeFunctionData("transfer", [params.to, amountWei]);
|