@moveflow/widget
Version:
> ⚠️ **This is a testnet version** of the MoveFlow Checkout Widget. It is intended for development and testing purposes only. Do not use for mainnet payments.
390 lines (389 loc) • 30.9 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { Avatar, Box, IconButton, MenuItem, Select, Typography, } from "@mui/material";
import { CheckCircle, ContentCopy, KeyboardArrowDown, WarningAmber, } from "@mui/icons-material";
import { coinConfig, networkIconConfig, NetworkType, } from "./config/coinConfig";
import ETHConnectButton from "./components/ETHConnectButton";
import SubscriptionButton from "./components/SubscriptionButton";
import { useContext, useEffect, useMemo, useState } from "react";
import { useSDK } from "@metamask/sdk-react";
import { copyAddress, stringWithEllipsis } from "./helper/string";
import useCoinAddress from "./hooks/useCoinAddress";
// import AptosConnectButton from "./components/aptosconnect";
import SubscriptionButtonAptos from "./components/subscriptionButtonAptos";
import Wallet from "./components/aptosWallet/Wallet";
import { AptosContext } from "./components/aptosWallet/AptosContext";
import VictionSubscription from "./components/victionSubscription";
import LightLinkSubscriptionButton from "./components/LightLinkSubscriptionButton";
import PharosSubscription from "./components/PharosSubscription";
const WidgetImpl = (props) => {
const aptosContext = useContext(AptosContext);
const { isConnectedAptos, address } = aptosContext || {};
const { setCoinAddress } = useCoinAddress();
const { connected, account, chainId } = useSDK();
const [copyReceiverAddress, setcopyReceiverAddress] = useState(false);
const [copySenderAddress, setcopySenderAddress] = useState(false);
const [showStepOneDetail, setShowStepOneDetail] = useState(!isConnectedAptos && !connected);
const [showStepTwoDetail, setShowStepTwoDetail] = useState(false);
useEffect(() => {
// Update showStepOneDetail when the wallet is connected
setShowStepOneDetail(!isConnectedAptos && !connected);
// Update showStepTwoDetail when the wallet is connected
setShowStepTwoDetail(isConnectedAptos || connected);
}, [isConnectedAptos, connected]);
// Modify the network state initialization
const [network, setNetwork] = useState(props.payment && props.payment.length > 0
? props.payment[0].network
: NetworkType.Goerli // Use a default value
);
// Similarly for paymentIndex and selectedPayment
const [paymentIndex, setPaymentIndex] = useState(0);
const [selectedPayment, setSelectedPayment] = useState(props.payment && props.payment.length > 0 ? props.payment[0] : null);
const paymentOptions = useMemo(() => {
let option = new Map();
for (let i = 0; i < props.payment.length; i++) {
if (networkIconConfig.get(props.payment[i].network) === undefined) {
continue;
}
if (option.get(props.payment[i].network) === undefined) {
option.set(props.payment[i].network, new Map());
}
const payment = props.payment[i];
const val = `${payment.coinType}`;
option.get(props.payment[i].network).set(i, val);
}
return option;
}, [props.payment]);
const chainOptions = useMemo(() => {
let networkTypes = new Set();
paymentOptions.forEach((_, key) => {
if (networkIconConfig.get(key) === undefined) {
return;
}
networkTypes.add({
name: key,
imgPath: networkIconConfig.get(key),
});
});
// console.log('chainOptions', networkTypes)
return Array.from(networkTypes);
}, [paymentOptions]);
const coinOptions = useMemo(() => {
let coinTypes = [];
if (paymentOptions.get(network) === undefined) {
return coinTypes;
}
paymentOptions.get(network).forEach((value, key) => {
coinTypes.push({
name: value,
idx: key,
});
});
// console.log('coinTypes', coinTypes);
return coinTypes;
}, [network, paymentOptions, chainOptions]);
useEffect(() => {
setSelectedPayment(props.payment[paymentIndex]);
}, [props.payment]);
// console.log("selectedPayment:", selectedPayment);
return (_jsx(Box, { sx: {
paddingTop: 2,
display: "flex",
flexDirection: "column",
gap: 2,
width: "100%",
minHeight: "100vh",
}, children: !props.payment || props.payment.length === 0 ? (
// No payment options case - show ONLY the warning message
_jsxs(Box, { sx: {
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
padding: "40px",
border: "1px dashed #484a53",
borderRadius: "5px",
marginTop: "50px",
maxWidth: "600px",
width: "100%",
background: "linear-gradient(96.29deg, #343640 0%, #343640 100%)",
}, children: [_jsx(WarningAmber, { sx: { fontSize: 60, color: "#f143e2", marginBottom: 2 } }), _jsx(Typography, { variant: "h5", sx: { color: "#FFFFFF", textAlign: "center", marginBottom: 2 }, children: "No Payment Options Available" }), _jsx(Typography, { variant: "body1", sx: { color: "#8a8d93", textAlign: "center", marginBottom: 3 }, children: "Please add at least one payment option to continue" })] })) : (_jsxs(_Fragment, { children: [_jsxs(Box, { sx: {
border: "1px solid #FFFFFF4D",
borderRadius: `${props.ui.container_border_radius}px`,
px: 8,
py: 4,
background: "linear-gradient(96.29deg, #343640 0%, #343640 100%), linear-gradient(0deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.1))",
}, children: [_jsx(Typography, { variant: "h3", sx: {
borderBottom: "1px solid #FFFFFF4D",
paddingBottom: 2,
fontFamily: props.ui.font_family,
}, children: props.basic_info.name }), _jsx(Typography, { variant: "h5", sx: {
marginTop: 2,
fontFamily: props.ui.font_family,
}, children: "Pay in Stream" }), _jsxs(Box, { sx: {
display: "flex",
flexDirection: "row",
gap: 2,
marginTop: 3,
marginBottom: 2,
}, children: [_jsxs(Typography, { variant: "h1", sx: {
height: "100%",
my: "auto",
fontFamily: props.ui?.font_family,
}, children: [selectedPayment && selectedPayment.amountType === "fixed"
? selectedPayment.streamRate
: selectedPayment && selectedPayment.depositAmount, " "] }), _jsxs(Box, { sx: {
display: "flex",
flexDirection: "column",
height: "100%",
}, children: [_jsxs(Typography, { variant: "body2", sx: {
fontFamily: props.ui?.font_family,
}, children: [selectedPayment?.coinType, " "] }), _jsxs(Typography, { variant: "body2", sx: {
fontFamily: props.ui?.font_family,
}, children: ["per ", selectedPayment?.rateType, " "] })] })] }), props.basic_info?.description && (_jsxs(_Fragment, { children: [_jsx(Typography, { variant: "h5", sx: {
borderTop: "1px solid #FFFFFF4D",
paddingTop: 2,
marginBottom: 2,
fontFamily: props.ui.font_family,
}, children: "Details" }), _jsx(Typography, { variant: "body1", sx: {
fontFamily: props.ui.font_family,
}, children: props.basic_info?.description })] }))] }), _jsxs(Box, { sx: {
display: "flex",
flexDirection: "column",
gap: 3,
border: "1px solid #FFFFFF4D",
borderRadius: `${props.ui.container_border_radius}px`,
px: 8,
py: 8,
background: "linear-gradient(96.29deg, #343640 0%, #343640 100%), linear-gradient(0deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.1))",
}, children: [_jsxs(Box, { sx: {
display: "flex",
flexDirection: "row",
justifyContent: "space-between",
borderBottom: "1px solid #FFFFFF4D",
paddingBottom: 2,
}, children: [_jsxs(Box, { sx: {
display: "flex",
flexDirection: "row",
alignItems: "center",
gap: 3,
}, children: [_jsx(Avatar, { sx: {
bgcolor: props.ui.primary_color,
width: 20,
height: 20,
}, children: _jsx(Typography, { variant: "body1", sx: {
color: props.ui.secondary_color,
fontFamily: props.ui.font_family,
}, children: "1" }) }), _jsx(Typography, { variant: "h4", component: "div", sx: {
fontFamily: props.ui.font_family,
}, children: "Select network and token" })] }), _jsx(IconButton, { "aria-label": "expand row", size: "small", onClick: () => {
setShowStepOneDetail(!showStepOneDetail);
setShowStepTwoDetail(!showStepTwoDetail);
}, children: _jsx(KeyboardArrowDown, { fill: "white" }) })] }), showStepOneDetail && (_jsxs(Box, { sx: {
display: "flex",
flexDirection: "column",
gap: 2,
}, children: [_jsxs(Box, { sx: {
display: "flex",
flexDirection: "row",
gap: 4,
}, children: [_jsx(Select, { labelId: "chain-select-label", id: "chain-select", value: network, onChange: (e) => {
setNetwork(e.target.value);
}, sx: {
width: "100%",
borderRadius: `${props.ui.field_border_radius}px`,
fontFamily: props.ui.font_family,
"& .MuiSelect-select": {
px: 4,
py: 2,
fontFamily: props.ui.font_family,
},
}, children: chainOptions.map((val) => {
console.log("val:", val);
return (_jsx(MenuItem, { value: val.name, children: _jsxs(Box, { sx: { display: "flex", flexDirection: "row" }, children: [_jsx("img", { alt: `${val.name} Logo`, src: val.imgPath, width: 25, height: 25 }), _jsx(Typography, { variant: "body1", style: {
marginLeft: "10px",
fontFamily: props.ui.font_family,
}, children: val.name })] }) }, val.name));
}) }), _jsx(Select, { labelId: "chain-select-label", id: "chain-select", value: paymentIndex, onChange: (e) => {
setPaymentIndex(e.target.value);
setSelectedPayment(props.payment[e.target.value]);
setCoinAddress(coinConfig[network].filter((v) => {
return (v.coinName ===
props.payment[e.target.value].coinType);
})[0].address);
}, sx: {
width: "100%",
borderRadius: `${props.ui.field_border_radius}px`,
"& .MuiSelect-select": {
px: 4,
py: 2,
},
}, children: coinOptions.map((val, index) => {
return (_jsx(MenuItem, { value: val.idx, children: _jsxs(Box, { sx: {
display: "flex",
flexDirection: "row",
}, children: [_jsx("img", { alt: "Eth Logo", src: coinConfig[network].filter((v) => {
const coinType = val.name.split("-")[0];
console.log("coinType:", coinType);
console.log("v.coinName:", v.coinName);
return coinType === v.coinName;
})[0].imagePath, width: 25, height: 25 }), _jsx(Typography, { variant: "body1", style: {
marginLeft: "10px",
fontFamily: props.ui.font_family,
}, children: val.name })] }) }, index));
}) })] }), _jsx(Box, { children: network === NetworkType.Aptos ? (
// Render Connect Wallet button for Aptos
_jsx(_Fragment, { children: _jsx("div", { style: { marginBottom: "-17px" }, children: _jsx(Wallet, {}) }) })) : (
// Render the default Connect Wallet button
_jsx(ETHConnectButton, { fontFamily: props.ui.font_family, borderRadius: props.ui.button_border_radius })) })] })), _jsxs(Box, { sx: {
display: "flex",
flexDirection: "row",
justifyContent: "space-between",
paddingBottom: 2,
borderBottom: "1px solid #FFFFFF4D",
}, children: [_jsxs(Box, { sx: {
display: "flex",
flexDirection: "row",
alignItems: "center",
gap: 3,
}, children: [_jsx(Avatar, { sx: {
bgcolor: props.ui.primary_color,
width: 20,
height: 20,
}, children: _jsx(Typography, { variant: "body1", sx: {
color: props.ui.secondary_color,
fontFamily: props.ui.font_family,
}, children: "2" }) }), _jsx(Typography, { variant: "h4", component: "div", sx: {
fontFamily: props.ui.font_family,
}, children: "Review the transaction(s)" })] }), _jsx(IconButton, { "aria-label": "expand row", size: "small", onClick: () => {
setShowStepTwoDetail(!showStepTwoDetail);
}, children: _jsx(KeyboardArrowDown, { fill: "white" }) })] }), _jsxs(Box, { sx: {
display: "flex",
flexDirection: "column",
gap: 4,
bottom: 0,
}, children: [showStepTwoDetail && (_jsxs(Box, { sx: {
display: "flex",
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
}, children: [_jsx(Box, { sx: {
display: "flex",
flexDirection: "column",
gap: 2,
}, children: _jsxs(Box, { sx: {
display: "flex",
justifyContent: "space-between",
alignItems: "center",
borderRadius: "8px",
border: "1px solid rgba(255, 255, 255, 0.1);",
minWidth: "180px",
height: "60px",
px: 3,
background: "linear-gradient(0deg, rgba(217, 217, 217, 0.2), rgba(217, 217, 217, 0.2)), linear-gradient(0deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.1))",
}, children: [_jsxs(Box, { sx: {
display: "flex",
flexDirection: "row",
alignItems: "center",
justifyContent: "start",
gap: 3,
}, children: [_jsx(Avatar, { children: _jsx("div", { style: {
overflow: "hidden",
width: "24px",
height: "24px",
backgroundColor: "rgb(241, 172, 2)",
borderRadius: "12px",
}, children: _jsxs("svg", { width: "24px", height: "24px", children: [_jsx("rect", { x: "0", y: "0", width: "24", height: "24", fill: "#FC8400", transform: "translate(0.09360401697918151 -0.013747316900765494) rotate(388.7 12 12)" }), _jsx("rect", { x: "0", y: "0", width: "24", height: "24", fill: "#245AE1", transform: "translate(11.965214621355102 -5.722361063311171) rotate(467.2 12 12)" }), _jsx("rect", { x: "0", y: "0", width: "24", height: "24", fill: "#01808C", transform: "translate(5.817023438467576 22.70924894631152) rotate(249.7 12 12)" })] }) }) }), _jsx(Typography, { variant: "body1", sx: {
fontFamily: props.ui.font_family,
}, children: stringWithEllipsis(network === NetworkType.Aptos
? address || ""
: account || "", 3) })] }), _jsx(IconButton, { onClick: () => {
const addressToCopy = network === NetworkType.Aptos
? address || ""
: account || "";
copyAddress(addressToCopy);
setcopySenderAddress(true);
// Reset the "copySenderAddress" state after a 2-second delay
setTimeout(() => {
setcopySenderAddress(false);
}, 2000);
}, children: copySenderAddress ? (_jsx(CheckCircle, { width: "2rem", height: "2rem", fontSize: "small", sx: { color: "purple.500" } })) : (_jsx(ContentCopy, { width: "2rem", height: "2rem", fontSize: "small", sx: { color: "purple.500" } })) })] }) }), _jsx(Box, { sx: {
flexGrow: 1,
flexShrink: 1,
}, children: _jsx("img", { src: "https://raw.githubusercontent.com/Move-Flow/assets/main/Streaming.gif", alt: "Streaming", className: "animated-gif", style: {
width: "100%",
height: "60px",
} }) }), _jsx(Box, { sx: {
display: "flex",
flexDirection: "column",
gap: 2,
}, children: _jsxs(Box, { sx: {
display: "flex",
justifyContent: "space-between",
alignItems: "center",
borderRadius: "8px",
border: "1px solid rgba(255, 255, 255, 0.1);",
minWidth: "180px",
height: "60px",
paddingLeft: 3,
paddingRight: 3,
background: "linear-gradient(0deg, rgba(217, 217, 217, 0.2), rgba(217, 217, 217, 0.2)), linear-gradient(0deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.1))",
}, children: [_jsxs(Box, { sx: {
display: "flex",
flexDirection: "row",
alignItems: "center",
justifyContent: "start",
gap: 3,
}, children: [_jsx(Avatar, { children: _jsx(Box, { children: _jsx("div", { style: {
overflow: "hidden",
width: "24px",
height: "24px",
backgroundColor: "rgb(241, 172, 2)",
borderRadius: "12px",
}, children: _jsxs("svg", { width: "24px", height: "24px", children: [_jsx("rect", { x: "0", y: "0", width: "24", height: "24", fill: "#1593F2", transform: "translate(5.374388038297389 -5.77804521151242) rotate(416.7 12 12)" }), _jsx("rect", { x: "0", y: "0", width: "24", height: "24", fill: "#FC7B00", transform: "translate(-7.631366435658614 6.643944436901061) rotate(156.5 12 12)" }), _jsx("rect", { x: "0", y: "0", width: "24", height: "24", fill: "#2461E1", transform: "translate(2.5498072745695954 23.409873335660436) rotate(179.5 12 12)" })] }) }) }) }), _jsx(Typography, { variant: "body1", sx: {
fontFamily: props.ui.font_family,
}, children: stringWithEllipsis(selectedPayment?.receiver || "", 3) })] }), _jsx(IconButton, { onClick: () => {
copyAddress(selectedPayment?.receiver || "");
setcopyReceiverAddress(true);
setTimeout(() => {
setcopyReceiverAddress(false);
}, 2000);
}, children: copyReceiverAddress ? (_jsx(CheckCircle, { width: "2rem", height: "2rem", fontSize: "small", sx: { color: "purple.500" } })) : (_jsx(ContentCopy, { width: "2rem", height: "2rem", fontSize: "small", sx: { color: "purple.500" } })) })] }) })] })), _jsx(Box, { sx: {
textAlign: "center",
}, children: _jsx(Typography, { variant: "body2", sx: { fontFamily: props.ui.font_family }, children: `${selectedPayment?.amountType === "fixed"
? selectedPayment?.streamRate
: "X"} ${selectedPayment?.coinType} per ${selectedPayment?.rateType}` }) })] }), _jsx(Box, { sx: {
width: "100%",
marginTop: 4,
textAlign: "center",
}, children: network === NetworkType.Viction ? (
// Render Viction-specific subscription logic
_jsx(VictionSubscription, { primaryColor: props.ui.primary_color, payment: selectedPayment, fontFamily: props.ui.font_family, borderRadius: props.ui.button_border_radius, chainName: "Viction" })) : network === NetworkType.Aptos ? (
// Render Aptos-specific subscription logic
_jsx(SubscriptionButtonAptos, { primaryColor: props.ui.primary_color, payment: selectedPayment, fontFamily: props.ui.font_family, borderRadius: props.ui.button_border_radius })) : network === NetworkType.Goerli ? (
// Render default Ethereum-specific subscription logic
_jsx(SubscriptionButton, { primaryColor: props.ui.primary_color, payment: selectedPayment, fontFamily: props.ui.font_family, borderRadius: props.ui.button_border_radius, chainName: "Goerli" })) : network === NetworkType.LightLink ? (_jsx(LightLinkSubscriptionButton, { primaryColor: props.ui.primary_color, payment: selectedPayment, fontFamily: props.ui.font_family, borderRadius: props.ui.button_border_radius, chainName: "Lightlink" })) : (
// Default/fallback case for Pharos or any other network
_jsx(PharosSubscription, { primaryColor: props.ui.primary_color, payment: selectedPayment, fontFamily: props.ui.font_family, borderRadius: props.ui.button_border_radius, chainName: "Pharos" })) })] }), _jsxs(Box, { sx: {
marginTop: 4,
width: "60%",
borderRadius: "8px",
gap: 1,
mx: "auto",
display: "flex",
flexDirection: "row",
justifyContent: "center",
alignItems: "center",
background: "linear-gradient(96.29deg, #343640 0%, #343640 100%), linear-gradient(0deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.1))",
}, children: [_jsx(Typography, { component: "div", variant: "h5", sx: {
textAlign: "center",
margin: 3,
color: "#FFFFFF6D",
padding: 1,
display: "inline",
fontFamily: props.ui.font_family,
}, children: "Powered by" }), _jsx(Box, { children: _jsx("img", { src: "https://raw.githubusercontent.com/Move-Flow/assets/34f95fcc68ae07c934c603826dac4d4170953908/mf_plogo.svg", alt: "mf", style: {
width: "120px",
height: "50px",
} }) })] })] })) }));
};
export default WidgetImpl;