@moneymq/react 0.1.2 → 0.2.1
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/LICENSE +21 -0
- package/dist/index.d.mts +27 -9
- package/dist/index.d.ts +27 -9
- package/dist/index.js +66 -55
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +66 -55
- package/dist/index.mjs.map +1 -1
- package/package.json +8 -8
package/dist/index.mjs
CHANGED
|
@@ -395,7 +395,7 @@ function MoneyMQProvider({
|
|
|
395
395
|
}
|
|
396
396
|
|
|
397
397
|
// src/pay-button.tsx
|
|
398
|
-
import { forwardRef, useEffect as useEffect3, useState as useState5 } from "react";
|
|
398
|
+
import React5, { forwardRef, useEffect as useEffect3, useState as useState5 } from "react";
|
|
399
399
|
|
|
400
400
|
// src/payment-modal.tsx
|
|
401
401
|
import { useCallback as useCallback3, useState as useState4 } from "react";
|
|
@@ -481,8 +481,9 @@ async function makeRequestWith402Handling(url, method, body, secretKeyHex, rpcUr
|
|
|
481
481
|
}
|
|
482
482
|
return data;
|
|
483
483
|
}
|
|
484
|
-
async function createSandboxPayment(apiUrl, rpcUrl, amount, currency, recipient, senderAddress, secretKeyHex,
|
|
484
|
+
async function createSandboxPayment(apiUrl, rpcUrl, amount, currency, recipient, senderAddress, secretKeyHex, lineItems) {
|
|
485
485
|
console.log("[MoneyMQ] Creating sandbox payment...", { amount, currency, recipient, senderAddress });
|
|
486
|
+
const description = lineItems && lineItems.length > 0 ? `Purchase - ${lineItems.map((item) => item.product.name).join(", ")}` : "Payment";
|
|
486
487
|
const paymentIntent = await makeRequestWith402Handling(
|
|
487
488
|
`${apiUrl}/catalog/v1/payment_intents`,
|
|
488
489
|
"POST",
|
|
@@ -491,7 +492,7 @@ async function createSandboxPayment(apiUrl, rpcUrl, amount, currency, recipient,
|
|
|
491
492
|
// Convert to cents (Stripe-style)
|
|
492
493
|
currency: currency.toLowerCase(),
|
|
493
494
|
customer: senderAddress,
|
|
494
|
-
description
|
|
495
|
+
description,
|
|
495
496
|
metadata: {
|
|
496
497
|
sender_address: senderAddress,
|
|
497
498
|
recipient_address: recipient
|
|
@@ -522,7 +523,7 @@ function PaymentModal({
|
|
|
522
523
|
amount,
|
|
523
524
|
currency,
|
|
524
525
|
recipient,
|
|
525
|
-
|
|
526
|
+
lineItems,
|
|
526
527
|
onSuccess,
|
|
527
528
|
onError,
|
|
528
529
|
accentColor = "#ec4899"
|
|
@@ -620,7 +621,7 @@ function PaymentModal({
|
|
|
620
621
|
recipient,
|
|
621
622
|
senderAddress,
|
|
622
623
|
secretKeyHex,
|
|
623
|
-
|
|
624
|
+
lineItems
|
|
624
625
|
);
|
|
625
626
|
setIsSending(false);
|
|
626
627
|
onSuccess?.(paymentId);
|
|
@@ -668,7 +669,7 @@ function PaymentModal({
|
|
|
668
669
|
setIsSending(false);
|
|
669
670
|
onError?.(err instanceof Error ? err : new Error(String(err)));
|
|
670
671
|
}
|
|
671
|
-
}, [publicKey, recipient, amount, currency, onSuccess, onError, onClose, selectedPaymentMethod, client.config.endpoint,
|
|
672
|
+
}, [publicKey, recipient, amount, currency, onSuccess, onError, onClose, selectedPaymentMethod, client.config.endpoint, lineItems]);
|
|
672
673
|
const canPay = (connected && publicKey || selectedPaymentMethod?.type === "sandbox_account") && recipient && !isSending;
|
|
673
674
|
if (!visible) return null;
|
|
674
675
|
const WalletIcon = () => /* @__PURE__ */ jsxs3("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: [
|
|
@@ -1157,7 +1158,38 @@ function PaymentModal({
|
|
|
1157
1158
|
},
|
|
1158
1159
|
children: [
|
|
1159
1160
|
/* @__PURE__ */ jsxs3("div", { style: { marginBottom: "1rem" }, children: [
|
|
1160
|
-
/* @__PURE__ */ jsx4("div", { style: {
|
|
1161
|
+
lineItems && lineItems.length > 0 && /* @__PURE__ */ jsx4("div", { style: { marginBottom: "0.75rem" }, children: lineItems.map((item, index) => /* @__PURE__ */ jsxs3(
|
|
1162
|
+
"div",
|
|
1163
|
+
{
|
|
1164
|
+
style: {
|
|
1165
|
+
display: "flex",
|
|
1166
|
+
justifyContent: "space-between",
|
|
1167
|
+
alignItems: "center",
|
|
1168
|
+
padding: "0.5rem 0",
|
|
1169
|
+
borderBottom: index < lineItems.length - 1 ? "1px solid #3a3a3c" : "none"
|
|
1170
|
+
},
|
|
1171
|
+
children: [
|
|
1172
|
+
/* @__PURE__ */ jsxs3("div", { style: { flex: 1 }, children: [
|
|
1173
|
+
/* @__PURE__ */ jsx4("div", { style: { fontSize: "0.875rem", color: "#fff", fontWeight: 500 }, children: item.product.name }),
|
|
1174
|
+
item.quantity > 1 && /* @__PURE__ */ jsxs3("div", { style: { fontSize: "0.75rem", color: "#8e8e93" }, children: [
|
|
1175
|
+
"Qty: ",
|
|
1176
|
+
item.quantity,
|
|
1177
|
+
" \xD7 ",
|
|
1178
|
+
(item.price.unit_amount / 100).toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 }),
|
|
1179
|
+
" ",
|
|
1180
|
+
item.price.currency.toUpperCase()
|
|
1181
|
+
] })
|
|
1182
|
+
] }),
|
|
1183
|
+
/* @__PURE__ */ jsxs3("div", { style: { fontSize: "0.875rem", color: "#fff", fontWeight: 500 }, children: [
|
|
1184
|
+
item.subtotal.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 }),
|
|
1185
|
+
" ",
|
|
1186
|
+
item.price.currency.toUpperCase()
|
|
1187
|
+
] })
|
|
1188
|
+
]
|
|
1189
|
+
},
|
|
1190
|
+
item.product.id + "-" + index
|
|
1191
|
+
)) }),
|
|
1192
|
+
/* @__PURE__ */ jsx4("div", { style: { fontSize: "0.875rem", color: "#8e8e93", marginBottom: "0.25rem" }, children: "Total" }),
|
|
1161
1193
|
/* @__PURE__ */ jsxs3("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [
|
|
1162
1194
|
/* @__PURE__ */ jsxs3("div", { style: { display: "flex", alignItems: "baseline", gap: "0.375rem" }, children: [
|
|
1163
1195
|
/* @__PURE__ */ jsx4("span", { style: { fontSize: "2rem", fontWeight: 600, color: "#fff" }, children: amount.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 }) }),
|
|
@@ -1326,9 +1358,7 @@ var outlineStyle = {
|
|
|
1326
1358
|
};
|
|
1327
1359
|
var PayButton = forwardRef(
|
|
1328
1360
|
function PayButton2({
|
|
1329
|
-
|
|
1330
|
-
price: priceObject,
|
|
1331
|
-
product: productObject,
|
|
1361
|
+
basket,
|
|
1332
1362
|
onSuccess,
|
|
1333
1363
|
onError,
|
|
1334
1364
|
variant = "solid",
|
|
@@ -1338,18 +1368,35 @@ var PayButton = forwardRef(
|
|
|
1338
1368
|
const client = useMoneyMQ();
|
|
1339
1369
|
const [isModalOpen, setIsModalOpen] = useState5(false);
|
|
1340
1370
|
const [isHovered, setIsHovered] = useState5(false);
|
|
1341
|
-
const
|
|
1342
|
-
const [isLoading, setIsLoading] = useState5(!hasPriceObject);
|
|
1371
|
+
const [isLoading, setIsLoading] = useState5(true);
|
|
1343
1372
|
const [error, setError] = useState5(null);
|
|
1344
|
-
const [amount, setAmount] = useState5(hasPriceObject ? priceObject.unit_amount / 100 : 0);
|
|
1345
|
-
const [currency, setCurrency] = useState5(hasPriceObject ? priceObject.currency.toUpperCase() : "USDC");
|
|
1346
1373
|
const [recipient, setRecipient] = useState5("");
|
|
1347
|
-
const
|
|
1374
|
+
const { totalAmount, currency, lineItems } = React5.useMemo(() => {
|
|
1375
|
+
if (!basket || basket.length === 0) {
|
|
1376
|
+
return { totalAmount: 0, currency: "USDC", lineItems: [] };
|
|
1377
|
+
}
|
|
1378
|
+
const baseCurrency = basket[0].price.currency.toUpperCase();
|
|
1379
|
+
const items = basket.map((item) => ({
|
|
1380
|
+
product: item.product,
|
|
1381
|
+
price: item.price,
|
|
1382
|
+
quantity: item.quantity ?? 1,
|
|
1383
|
+
subtotal: item.price.unit_amount / 100 * (item.quantity ?? 1)
|
|
1384
|
+
}));
|
|
1385
|
+
const total = items.reduce((sum, item) => sum + item.subtotal, 0);
|
|
1386
|
+
return {
|
|
1387
|
+
totalAmount: total,
|
|
1388
|
+
currency: baseCurrency,
|
|
1389
|
+
lineItems: items
|
|
1390
|
+
};
|
|
1391
|
+
}, [basket]);
|
|
1348
1392
|
useEffect3(() => {
|
|
1349
1393
|
async function fetchPaymentDetails() {
|
|
1350
1394
|
setIsLoading(true);
|
|
1351
1395
|
setError(null);
|
|
1352
1396
|
try {
|
|
1397
|
+
if (!basket || basket.length === 0) {
|
|
1398
|
+
throw new Error("Basket is empty");
|
|
1399
|
+
}
|
|
1353
1400
|
const apiUrl = client.config.endpoint;
|
|
1354
1401
|
const configResponse = await fetch(`${apiUrl}/config`);
|
|
1355
1402
|
if (!configResponse.ok) {
|
|
@@ -1359,42 +1406,6 @@ var PayButton = forwardRef(
|
|
|
1359
1406
|
if (config.x402?.payoutAccount?.address) {
|
|
1360
1407
|
setRecipient(config.x402.payoutAccount.address);
|
|
1361
1408
|
}
|
|
1362
|
-
if (hasPriceObject) {
|
|
1363
|
-
setAmount(priceObject.unit_amount / 100);
|
|
1364
|
-
setCurrency(priceObject.currency.toUpperCase());
|
|
1365
|
-
if (productObject) {
|
|
1366
|
-
setProductName(productObject.name);
|
|
1367
|
-
} else if (priceObject.product) {
|
|
1368
|
-
try {
|
|
1369
|
-
const productResponse = await fetch(`${apiUrl}/catalog/v1/products/${priceObject.product}`);
|
|
1370
|
-
if (productResponse.ok) {
|
|
1371
|
-
const product = await productResponse.json();
|
|
1372
|
-
setProductName(product.name);
|
|
1373
|
-
}
|
|
1374
|
-
} catch {
|
|
1375
|
-
}
|
|
1376
|
-
}
|
|
1377
|
-
} else if (priceId) {
|
|
1378
|
-
const priceResponse = await fetch(`${apiUrl}/catalog/v1/prices/${priceId}`);
|
|
1379
|
-
if (!priceResponse.ok) {
|
|
1380
|
-
throw new Error(`Failed to fetch price: ${priceResponse.status}`);
|
|
1381
|
-
}
|
|
1382
|
-
const price = await priceResponse.json();
|
|
1383
|
-
setAmount(price.unit_amount / 100);
|
|
1384
|
-
setCurrency(price.currency.toUpperCase());
|
|
1385
|
-
if (price.product) {
|
|
1386
|
-
try {
|
|
1387
|
-
const productResponse = await fetch(`${apiUrl}/catalog/v1/products/${price.product}`);
|
|
1388
|
-
if (productResponse.ok) {
|
|
1389
|
-
const product = await productResponse.json();
|
|
1390
|
-
setProductName(product.name);
|
|
1391
|
-
}
|
|
1392
|
-
} catch {
|
|
1393
|
-
}
|
|
1394
|
-
}
|
|
1395
|
-
} else {
|
|
1396
|
-
throw new Error("Either priceId or price object is required");
|
|
1397
|
-
}
|
|
1398
1409
|
} catch (err) {
|
|
1399
1410
|
console.error("[PayButton] Error fetching payment details:", err);
|
|
1400
1411
|
const errorMessage = err instanceof Error ? err.message : "Failed to load payment details";
|
|
@@ -1405,7 +1416,7 @@ var PayButton = forwardRef(
|
|
|
1405
1416
|
}
|
|
1406
1417
|
}
|
|
1407
1418
|
fetchPaymentDetails();
|
|
1408
|
-
}, [
|
|
1419
|
+
}, [basket, client.config.endpoint, onError]);
|
|
1409
1420
|
const handleClick = () => {
|
|
1410
1421
|
if (!isLoading && !error) {
|
|
1411
1422
|
setIsModalOpen(true);
|
|
@@ -1414,7 +1425,7 @@ var PayButton = forwardRef(
|
|
|
1414
1425
|
const handlePaymentSuccess = (signature) => {
|
|
1415
1426
|
const payment = {
|
|
1416
1427
|
id: `pay_${Date.now()}`,
|
|
1417
|
-
amount,
|
|
1428
|
+
amount: totalAmount,
|
|
1418
1429
|
currency,
|
|
1419
1430
|
status: "completed",
|
|
1420
1431
|
signature
|
|
@@ -1450,10 +1461,10 @@ var PayButton = forwardRef(
|
|
|
1450
1461
|
{
|
|
1451
1462
|
visible: isModalOpen,
|
|
1452
1463
|
onClose: () => setIsModalOpen(false),
|
|
1453
|
-
amount,
|
|
1464
|
+
amount: totalAmount,
|
|
1454
1465
|
currency,
|
|
1455
1466
|
recipient,
|
|
1456
|
-
|
|
1467
|
+
lineItems,
|
|
1457
1468
|
onSuccess: handlePaymentSuccess,
|
|
1458
1469
|
onError: handlePaymentError
|
|
1459
1470
|
}
|