@settlr/sdk 0.2.0 → 0.3.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/README.md +17 -1
- package/dist/index.d.mts +106 -1
- package/dist/index.d.ts +106 -1
- package/dist/index.js +191 -0
- package/dist/index.mjs +191 -1
- package/package.json +31 -7
package/README.md
CHANGED
|
@@ -1,6 +1,22 @@
|
|
|
1
1
|
# @settlr/sdk
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@settlr/sdk)
|
|
4
|
+
[](https://www.npmjs.com/package/@settlr/sdk)
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
6
|
+
|
|
7
|
+
> **Settlr** - Accept Solana USDC payments in games and apps. Email checkout, gasless transactions, no wallet required.
|
|
8
|
+
|
|
9
|
+
🌐 **Website:** [settlr.dev](https://settlr.dev)
|
|
10
|
+
📖 **Docs:** [settlr.dev/docs](https://settlr.dev/docs)
|
|
11
|
+
🎮 **Demo:** [settlr.dev/demo](https://settlr.dev/demo)
|
|
12
|
+
|
|
13
|
+
## Why Settlr?
|
|
14
|
+
|
|
15
|
+
- ✅ **No wallet required** - Users pay with just an email
|
|
16
|
+
- ✅ **Gasless transactions** - No SOL needed for fees
|
|
17
|
+
- ✅ **USDC on Solana** - Fast, cheap, stable payments
|
|
18
|
+
- ✅ **Drop-in components** - React components ready to use
|
|
19
|
+
- ✅ **Gaming focused** - Built for in-game purchases
|
|
4
20
|
|
|
5
21
|
## Installation
|
|
6
22
|
|
package/dist/index.d.mts
CHANGED
|
@@ -584,6 +584,111 @@ declare function usePaymentLink(config: {
|
|
|
584
584
|
cancelUrl?: string;
|
|
585
585
|
}) => string>[0]) => Promise<string>;
|
|
586
586
|
};
|
|
587
|
+
/**
|
|
588
|
+
* Payment Modal - Iframe-based checkout that keeps users on your site
|
|
589
|
+
*
|
|
590
|
+
* @example
|
|
591
|
+
* ```tsx
|
|
592
|
+
* import { PaymentModal } from '@settlr/sdk';
|
|
593
|
+
*
|
|
594
|
+
* function ProductPage() {
|
|
595
|
+
* const [showPayment, setShowPayment] = useState(false);
|
|
596
|
+
*
|
|
597
|
+
* return (
|
|
598
|
+
* <>
|
|
599
|
+
* <button onClick={() => setShowPayment(true)}>
|
|
600
|
+
* Buy Now - $49.99
|
|
601
|
+
* </button>
|
|
602
|
+
*
|
|
603
|
+
* {showPayment && (
|
|
604
|
+
* <PaymentModal
|
|
605
|
+
* amount={49.99}
|
|
606
|
+
* merchantName="Arena GG"
|
|
607
|
+
* merchantWallet="YOUR_WALLET_ADDRESS"
|
|
608
|
+
* memo="Tournament Entry"
|
|
609
|
+
* onSuccess={(result) => {
|
|
610
|
+
* console.log('Paid!', result.signature);
|
|
611
|
+
* setShowPayment(false);
|
|
612
|
+
* }}
|
|
613
|
+
* onClose={() => setShowPayment(false)}
|
|
614
|
+
* />
|
|
615
|
+
* )}
|
|
616
|
+
* </>
|
|
617
|
+
* );
|
|
618
|
+
* }
|
|
619
|
+
* ```
|
|
620
|
+
*/
|
|
621
|
+
interface PaymentModalProps {
|
|
622
|
+
/** Payment amount in USDC */
|
|
623
|
+
amount: number;
|
|
624
|
+
/** Merchant display name */
|
|
625
|
+
merchantName: string;
|
|
626
|
+
/** Merchant wallet address */
|
|
627
|
+
merchantWallet: string;
|
|
628
|
+
/** Optional memo/description */
|
|
629
|
+
memo?: string;
|
|
630
|
+
/** Optional order ID */
|
|
631
|
+
orderId?: string;
|
|
632
|
+
/** Called when payment succeeds */
|
|
633
|
+
onSuccess?: (result: {
|
|
634
|
+
signature: string;
|
|
635
|
+
amount: number;
|
|
636
|
+
}) => void;
|
|
637
|
+
/** Called when modal is closed */
|
|
638
|
+
onClose?: () => void;
|
|
639
|
+
/** Called on error */
|
|
640
|
+
onError?: (error: Error) => void;
|
|
641
|
+
/** Checkout base URL (default: https://settlr.dev/checkout) */
|
|
642
|
+
checkoutUrl?: string;
|
|
643
|
+
}
|
|
644
|
+
declare function PaymentModal({ amount, merchantName, merchantWallet, memo, orderId, onSuccess, onClose, onError, checkoutUrl, }: PaymentModalProps): react_jsx_runtime.JSX.Element;
|
|
645
|
+
/**
|
|
646
|
+
* Hook to open payment modal programmatically
|
|
647
|
+
*
|
|
648
|
+
* @example
|
|
649
|
+
* ```tsx
|
|
650
|
+
* import { usePaymentModal } from '@settlr/sdk';
|
|
651
|
+
*
|
|
652
|
+
* function ProductPage() {
|
|
653
|
+
* const { openPayment, PaymentModalComponent } = usePaymentModal({
|
|
654
|
+
* merchantName: "Arena GG",
|
|
655
|
+
* merchantWallet: "YOUR_WALLET",
|
|
656
|
+
* });
|
|
657
|
+
*
|
|
658
|
+
* return (
|
|
659
|
+
* <>
|
|
660
|
+
* <button onClick={() => openPayment({
|
|
661
|
+
* amount: 49.99,
|
|
662
|
+
* memo: "Tournament Entry",
|
|
663
|
+
* onSuccess: (result) => console.log("Paid!", result),
|
|
664
|
+
* })}>
|
|
665
|
+
* Buy Now
|
|
666
|
+
* </button>
|
|
667
|
+
* <PaymentModalComponent />
|
|
668
|
+
* </>
|
|
669
|
+
* );
|
|
670
|
+
* }
|
|
671
|
+
* ```
|
|
672
|
+
*/
|
|
673
|
+
declare function usePaymentModal(config: {
|
|
674
|
+
merchantName: string;
|
|
675
|
+
merchantWallet: string;
|
|
676
|
+
checkoutUrl?: string;
|
|
677
|
+
}): {
|
|
678
|
+
openPayment: (options: {
|
|
679
|
+
amount: number;
|
|
680
|
+
memo?: string;
|
|
681
|
+
orderId?: string;
|
|
682
|
+
onSuccess?: (result: {
|
|
683
|
+
signature: string;
|
|
684
|
+
amount: number;
|
|
685
|
+
}) => void;
|
|
686
|
+
onError?: (error: Error) => void;
|
|
687
|
+
}) => void;
|
|
688
|
+
closePayment: () => void;
|
|
689
|
+
isOpen: boolean;
|
|
690
|
+
PaymentModalComponent: () => react_jsx_runtime.JSX.Element | null;
|
|
691
|
+
};
|
|
587
692
|
|
|
588
693
|
/**
|
|
589
694
|
* Verify a webhook signature
|
|
@@ -667,4 +772,4 @@ declare function createWebhookHandler(options: {
|
|
|
667
772
|
onError?: (error: Error) => void;
|
|
668
773
|
}): (req: any, res: any) => Promise<void>;
|
|
669
774
|
|
|
670
|
-
export { BuyButton, type BuyButtonProps, CheckoutWidget, type CheckoutWidgetProps, type CreatePaymentOptions, type MerchantConfig, type Payment, type PaymentResult, type PaymentStatus, SETTLR_CHECKOUT_URL, SUPPORTED_NETWORKS, Settlr, type SettlrConfig, SettlrProvider, type TransactionOptions, USDC_MINT_DEVNET, USDC_MINT_MAINNET, type WebhookEventType, type WebhookHandler, type WebhookHandlers, type WebhookPayload, createWebhookHandler, formatUSDC, parseUSDC, parseWebhookPayload, shortenAddress, usePaymentLink, useSettlr, verifyWebhookSignature };
|
|
775
|
+
export { BuyButton, type BuyButtonProps, CheckoutWidget, type CheckoutWidgetProps, type CreatePaymentOptions, type MerchantConfig, type Payment, PaymentModal, type PaymentModalProps, type PaymentResult, type PaymentStatus, SETTLR_CHECKOUT_URL, SUPPORTED_NETWORKS, Settlr, type SettlrConfig, SettlrProvider, type TransactionOptions, USDC_MINT_DEVNET, USDC_MINT_MAINNET, type WebhookEventType, type WebhookHandler, type WebhookHandlers, type WebhookPayload, createWebhookHandler, formatUSDC, parseUSDC, parseWebhookPayload, shortenAddress, usePaymentLink, usePaymentModal, useSettlr, verifyWebhookSignature };
|
package/dist/index.d.ts
CHANGED
|
@@ -584,6 +584,111 @@ declare function usePaymentLink(config: {
|
|
|
584
584
|
cancelUrl?: string;
|
|
585
585
|
}) => string>[0]) => Promise<string>;
|
|
586
586
|
};
|
|
587
|
+
/**
|
|
588
|
+
* Payment Modal - Iframe-based checkout that keeps users on your site
|
|
589
|
+
*
|
|
590
|
+
* @example
|
|
591
|
+
* ```tsx
|
|
592
|
+
* import { PaymentModal } from '@settlr/sdk';
|
|
593
|
+
*
|
|
594
|
+
* function ProductPage() {
|
|
595
|
+
* const [showPayment, setShowPayment] = useState(false);
|
|
596
|
+
*
|
|
597
|
+
* return (
|
|
598
|
+
* <>
|
|
599
|
+
* <button onClick={() => setShowPayment(true)}>
|
|
600
|
+
* Buy Now - $49.99
|
|
601
|
+
* </button>
|
|
602
|
+
*
|
|
603
|
+
* {showPayment && (
|
|
604
|
+
* <PaymentModal
|
|
605
|
+
* amount={49.99}
|
|
606
|
+
* merchantName="Arena GG"
|
|
607
|
+
* merchantWallet="YOUR_WALLET_ADDRESS"
|
|
608
|
+
* memo="Tournament Entry"
|
|
609
|
+
* onSuccess={(result) => {
|
|
610
|
+
* console.log('Paid!', result.signature);
|
|
611
|
+
* setShowPayment(false);
|
|
612
|
+
* }}
|
|
613
|
+
* onClose={() => setShowPayment(false)}
|
|
614
|
+
* />
|
|
615
|
+
* )}
|
|
616
|
+
* </>
|
|
617
|
+
* );
|
|
618
|
+
* }
|
|
619
|
+
* ```
|
|
620
|
+
*/
|
|
621
|
+
interface PaymentModalProps {
|
|
622
|
+
/** Payment amount in USDC */
|
|
623
|
+
amount: number;
|
|
624
|
+
/** Merchant display name */
|
|
625
|
+
merchantName: string;
|
|
626
|
+
/** Merchant wallet address */
|
|
627
|
+
merchantWallet: string;
|
|
628
|
+
/** Optional memo/description */
|
|
629
|
+
memo?: string;
|
|
630
|
+
/** Optional order ID */
|
|
631
|
+
orderId?: string;
|
|
632
|
+
/** Called when payment succeeds */
|
|
633
|
+
onSuccess?: (result: {
|
|
634
|
+
signature: string;
|
|
635
|
+
amount: number;
|
|
636
|
+
}) => void;
|
|
637
|
+
/** Called when modal is closed */
|
|
638
|
+
onClose?: () => void;
|
|
639
|
+
/** Called on error */
|
|
640
|
+
onError?: (error: Error) => void;
|
|
641
|
+
/** Checkout base URL (default: https://settlr.dev/checkout) */
|
|
642
|
+
checkoutUrl?: string;
|
|
643
|
+
}
|
|
644
|
+
declare function PaymentModal({ amount, merchantName, merchantWallet, memo, orderId, onSuccess, onClose, onError, checkoutUrl, }: PaymentModalProps): react_jsx_runtime.JSX.Element;
|
|
645
|
+
/**
|
|
646
|
+
* Hook to open payment modal programmatically
|
|
647
|
+
*
|
|
648
|
+
* @example
|
|
649
|
+
* ```tsx
|
|
650
|
+
* import { usePaymentModal } from '@settlr/sdk';
|
|
651
|
+
*
|
|
652
|
+
* function ProductPage() {
|
|
653
|
+
* const { openPayment, PaymentModalComponent } = usePaymentModal({
|
|
654
|
+
* merchantName: "Arena GG",
|
|
655
|
+
* merchantWallet: "YOUR_WALLET",
|
|
656
|
+
* });
|
|
657
|
+
*
|
|
658
|
+
* return (
|
|
659
|
+
* <>
|
|
660
|
+
* <button onClick={() => openPayment({
|
|
661
|
+
* amount: 49.99,
|
|
662
|
+
* memo: "Tournament Entry",
|
|
663
|
+
* onSuccess: (result) => console.log("Paid!", result),
|
|
664
|
+
* })}>
|
|
665
|
+
* Buy Now
|
|
666
|
+
* </button>
|
|
667
|
+
* <PaymentModalComponent />
|
|
668
|
+
* </>
|
|
669
|
+
* );
|
|
670
|
+
* }
|
|
671
|
+
* ```
|
|
672
|
+
*/
|
|
673
|
+
declare function usePaymentModal(config: {
|
|
674
|
+
merchantName: string;
|
|
675
|
+
merchantWallet: string;
|
|
676
|
+
checkoutUrl?: string;
|
|
677
|
+
}): {
|
|
678
|
+
openPayment: (options: {
|
|
679
|
+
amount: number;
|
|
680
|
+
memo?: string;
|
|
681
|
+
orderId?: string;
|
|
682
|
+
onSuccess?: (result: {
|
|
683
|
+
signature: string;
|
|
684
|
+
amount: number;
|
|
685
|
+
}) => void;
|
|
686
|
+
onError?: (error: Error) => void;
|
|
687
|
+
}) => void;
|
|
688
|
+
closePayment: () => void;
|
|
689
|
+
isOpen: boolean;
|
|
690
|
+
PaymentModalComponent: () => react_jsx_runtime.JSX.Element | null;
|
|
691
|
+
};
|
|
587
692
|
|
|
588
693
|
/**
|
|
589
694
|
* Verify a webhook signature
|
|
@@ -667,4 +772,4 @@ declare function createWebhookHandler(options: {
|
|
|
667
772
|
onError?: (error: Error) => void;
|
|
668
773
|
}): (req: any, res: any) => Promise<void>;
|
|
669
774
|
|
|
670
|
-
export { BuyButton, type BuyButtonProps, CheckoutWidget, type CheckoutWidgetProps, type CreatePaymentOptions, type MerchantConfig, type Payment, type PaymentResult, type PaymentStatus, SETTLR_CHECKOUT_URL, SUPPORTED_NETWORKS, Settlr, type SettlrConfig, SettlrProvider, type TransactionOptions, USDC_MINT_DEVNET, USDC_MINT_MAINNET, type WebhookEventType, type WebhookHandler, type WebhookHandlers, type WebhookPayload, createWebhookHandler, formatUSDC, parseUSDC, parseWebhookPayload, shortenAddress, usePaymentLink, useSettlr, verifyWebhookSignature };
|
|
775
|
+
export { BuyButton, type BuyButtonProps, CheckoutWidget, type CheckoutWidgetProps, type CreatePaymentOptions, type MerchantConfig, type Payment, PaymentModal, type PaymentModalProps, type PaymentResult, type PaymentStatus, SETTLR_CHECKOUT_URL, SUPPORTED_NETWORKS, Settlr, type SettlrConfig, SettlrProvider, type TransactionOptions, USDC_MINT_DEVNET, USDC_MINT_MAINNET, type WebhookEventType, type WebhookHandler, type WebhookHandlers, type WebhookPayload, createWebhookHandler, formatUSDC, parseUSDC, parseWebhookPayload, shortenAddress, usePaymentLink, usePaymentModal, useSettlr, verifyWebhookSignature };
|
package/dist/index.js
CHANGED
|
@@ -32,6 +32,7 @@ var index_exports = {};
|
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
BuyButton: () => BuyButton,
|
|
34
34
|
CheckoutWidget: () => CheckoutWidget,
|
|
35
|
+
PaymentModal: () => PaymentModal,
|
|
35
36
|
SETTLR_CHECKOUT_URL: () => SETTLR_CHECKOUT_URL,
|
|
36
37
|
SUPPORTED_NETWORKS: () => SUPPORTED_NETWORKS,
|
|
37
38
|
Settlr: () => Settlr,
|
|
@@ -44,6 +45,7 @@ __export(index_exports, {
|
|
|
44
45
|
parseWebhookPayload: () => parseWebhookPayload,
|
|
45
46
|
shortenAddress: () => shortenAddress,
|
|
46
47
|
usePaymentLink: () => usePaymentLink,
|
|
48
|
+
usePaymentModal: () => usePaymentModal,
|
|
47
49
|
useSettlr: () => useSettlr,
|
|
48
50
|
verifyWebhookSignature: () => verifyWebhookSignature
|
|
49
51
|
});
|
|
@@ -893,6 +895,193 @@ function usePaymentLink(config) {
|
|
|
893
895
|
generateQRCode
|
|
894
896
|
};
|
|
895
897
|
}
|
|
898
|
+
var modalStyles = {
|
|
899
|
+
overlay: {
|
|
900
|
+
position: "fixed",
|
|
901
|
+
top: 0,
|
|
902
|
+
left: 0,
|
|
903
|
+
right: 0,
|
|
904
|
+
bottom: 0,
|
|
905
|
+
backgroundColor: "rgba(0, 0, 0, 0.8)",
|
|
906
|
+
backdropFilter: "blur(4px)",
|
|
907
|
+
display: "flex",
|
|
908
|
+
alignItems: "center",
|
|
909
|
+
justifyContent: "center",
|
|
910
|
+
zIndex: 9999,
|
|
911
|
+
padding: "16px"
|
|
912
|
+
},
|
|
913
|
+
container: {
|
|
914
|
+
position: "relative",
|
|
915
|
+
width: "100%",
|
|
916
|
+
maxWidth: "480px",
|
|
917
|
+
height: "90vh",
|
|
918
|
+
maxHeight: "700px",
|
|
919
|
+
backgroundColor: "#12121a",
|
|
920
|
+
borderRadius: "16px",
|
|
921
|
+
overflow: "hidden",
|
|
922
|
+
boxShadow: "0 25px 50px -12px rgba(0, 0, 0, 0.5)"
|
|
923
|
+
},
|
|
924
|
+
closeButton: {
|
|
925
|
+
position: "absolute",
|
|
926
|
+
top: "12px",
|
|
927
|
+
right: "12px",
|
|
928
|
+
width: "32px",
|
|
929
|
+
height: "32px",
|
|
930
|
+
borderRadius: "50%",
|
|
931
|
+
backgroundColor: "rgba(255, 255, 255, 0.1)",
|
|
932
|
+
border: "none",
|
|
933
|
+
cursor: "pointer",
|
|
934
|
+
display: "flex",
|
|
935
|
+
alignItems: "center",
|
|
936
|
+
justifyContent: "center",
|
|
937
|
+
zIndex: 10,
|
|
938
|
+
color: "white",
|
|
939
|
+
fontSize: "18px",
|
|
940
|
+
transition: "background-color 0.2s"
|
|
941
|
+
},
|
|
942
|
+
iframe: {
|
|
943
|
+
width: "100%",
|
|
944
|
+
height: "100%",
|
|
945
|
+
border: "none"
|
|
946
|
+
},
|
|
947
|
+
loading: {
|
|
948
|
+
position: "absolute",
|
|
949
|
+
top: "50%",
|
|
950
|
+
left: "50%",
|
|
951
|
+
transform: "translate(-50%, -50%)",
|
|
952
|
+
color: "white",
|
|
953
|
+
fontSize: "14px",
|
|
954
|
+
display: "flex",
|
|
955
|
+
flexDirection: "column",
|
|
956
|
+
alignItems: "center",
|
|
957
|
+
gap: "12px"
|
|
958
|
+
}
|
|
959
|
+
};
|
|
960
|
+
function PaymentModal({
|
|
961
|
+
amount,
|
|
962
|
+
merchantName,
|
|
963
|
+
merchantWallet,
|
|
964
|
+
memo,
|
|
965
|
+
orderId,
|
|
966
|
+
onSuccess,
|
|
967
|
+
onClose,
|
|
968
|
+
onError,
|
|
969
|
+
checkoutUrl = "https://settlr.dev/checkout"
|
|
970
|
+
}) {
|
|
971
|
+
const [loading, setLoading] = (0, import_react2.useState)(true);
|
|
972
|
+
const params = new URLSearchParams({
|
|
973
|
+
amount: amount.toString(),
|
|
974
|
+
merchant: merchantName,
|
|
975
|
+
to: merchantWallet,
|
|
976
|
+
embed: "true"
|
|
977
|
+
});
|
|
978
|
+
if (memo) params.set("memo", memo);
|
|
979
|
+
if (orderId) params.set("orderId", orderId);
|
|
980
|
+
const iframeSrc = `${checkoutUrl}?${params.toString()}`;
|
|
981
|
+
(0, import_react2.useEffect)(() => {
|
|
982
|
+
const handleMessage = (event) => {
|
|
983
|
+
if (!event.origin.includes("settlr.dev") && !event.origin.includes("localhost")) {
|
|
984
|
+
return;
|
|
985
|
+
}
|
|
986
|
+
const { type, data } = event.data || {};
|
|
987
|
+
switch (type) {
|
|
988
|
+
case "settlr:success":
|
|
989
|
+
onSuccess?.({
|
|
990
|
+
signature: data.signature,
|
|
991
|
+
amount: data.amount || amount
|
|
992
|
+
});
|
|
993
|
+
break;
|
|
994
|
+
case "settlr:error":
|
|
995
|
+
onError?.(new Error(data.message || "Payment failed"));
|
|
996
|
+
break;
|
|
997
|
+
case "settlr:close":
|
|
998
|
+
onClose?.();
|
|
999
|
+
break;
|
|
1000
|
+
}
|
|
1001
|
+
};
|
|
1002
|
+
window.addEventListener("message", handleMessage);
|
|
1003
|
+
return () => window.removeEventListener("message", handleMessage);
|
|
1004
|
+
}, [amount, onSuccess, onError, onClose]);
|
|
1005
|
+
(0, import_react2.useEffect)(() => {
|
|
1006
|
+
const handleEscape = (e) => {
|
|
1007
|
+
if (e.key === "Escape") onClose?.();
|
|
1008
|
+
};
|
|
1009
|
+
window.addEventListener("keydown", handleEscape);
|
|
1010
|
+
return () => window.removeEventListener("keydown", handleEscape);
|
|
1011
|
+
}, [onClose]);
|
|
1012
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: modalStyles.overlay, onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: modalStyles.container, onClick: (e) => e.stopPropagation(), children: [
|
|
1013
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1014
|
+
"button",
|
|
1015
|
+
{
|
|
1016
|
+
style: modalStyles.closeButton,
|
|
1017
|
+
onClick: onClose,
|
|
1018
|
+
onMouseOver: (e) => e.currentTarget.style.backgroundColor = "rgba(255, 255, 255, 0.2)",
|
|
1019
|
+
onMouseOut: (e) => e.currentTarget.style.backgroundColor = "rgba(255, 255, 255, 0.1)",
|
|
1020
|
+
children: "\u2715"
|
|
1021
|
+
}
|
|
1022
|
+
),
|
|
1023
|
+
loading && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: modalStyles.loading, children: [
|
|
1024
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, {}),
|
|
1025
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "Loading checkout..." })
|
|
1026
|
+
] }),
|
|
1027
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1028
|
+
"iframe",
|
|
1029
|
+
{
|
|
1030
|
+
src: iframeSrc,
|
|
1031
|
+
style: {
|
|
1032
|
+
...modalStyles.iframe,
|
|
1033
|
+
opacity: loading ? 0 : 1
|
|
1034
|
+
},
|
|
1035
|
+
onLoad: () => setLoading(false),
|
|
1036
|
+
allow: "payment"
|
|
1037
|
+
}
|
|
1038
|
+
)
|
|
1039
|
+
] }) });
|
|
1040
|
+
}
|
|
1041
|
+
function usePaymentModal(config) {
|
|
1042
|
+
const [modalState, setModalState] = (0, import_react2.useState)({
|
|
1043
|
+
isOpen: false,
|
|
1044
|
+
amount: 0
|
|
1045
|
+
});
|
|
1046
|
+
const openPayment = (0, import_react2.useCallback)(
|
|
1047
|
+
(options) => {
|
|
1048
|
+
setModalState({
|
|
1049
|
+
isOpen: true,
|
|
1050
|
+
...options
|
|
1051
|
+
});
|
|
1052
|
+
},
|
|
1053
|
+
[]
|
|
1054
|
+
);
|
|
1055
|
+
const closePayment = (0, import_react2.useCallback)(() => {
|
|
1056
|
+
setModalState((prev) => ({ ...prev, isOpen: false }));
|
|
1057
|
+
}, []);
|
|
1058
|
+
const PaymentModalComponent = (0, import_react2.useCallback)(() => {
|
|
1059
|
+
if (!modalState.isOpen) return null;
|
|
1060
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1061
|
+
PaymentModal,
|
|
1062
|
+
{
|
|
1063
|
+
amount: modalState.amount,
|
|
1064
|
+
merchantName: config.merchantName,
|
|
1065
|
+
merchantWallet: config.merchantWallet,
|
|
1066
|
+
memo: modalState.memo,
|
|
1067
|
+
orderId: modalState.orderId,
|
|
1068
|
+
checkoutUrl: config.checkoutUrl,
|
|
1069
|
+
onSuccess: (result) => {
|
|
1070
|
+
modalState.onSuccess?.(result);
|
|
1071
|
+
closePayment();
|
|
1072
|
+
},
|
|
1073
|
+
onError: modalState.onError,
|
|
1074
|
+
onClose: closePayment
|
|
1075
|
+
}
|
|
1076
|
+
);
|
|
1077
|
+
}, [modalState, config, closePayment]);
|
|
1078
|
+
return {
|
|
1079
|
+
openPayment,
|
|
1080
|
+
closePayment,
|
|
1081
|
+
isOpen: modalState.isOpen,
|
|
1082
|
+
PaymentModalComponent
|
|
1083
|
+
};
|
|
1084
|
+
}
|
|
896
1085
|
|
|
897
1086
|
// src/webhooks.ts
|
|
898
1087
|
var import_crypto = __toESM(require("crypto"));
|
|
@@ -956,6 +1145,7 @@ function createWebhookHandler(options) {
|
|
|
956
1145
|
0 && (module.exports = {
|
|
957
1146
|
BuyButton,
|
|
958
1147
|
CheckoutWidget,
|
|
1148
|
+
PaymentModal,
|
|
959
1149
|
SETTLR_CHECKOUT_URL,
|
|
960
1150
|
SUPPORTED_NETWORKS,
|
|
961
1151
|
Settlr,
|
|
@@ -968,6 +1158,7 @@ function createWebhookHandler(options) {
|
|
|
968
1158
|
parseWebhookPayload,
|
|
969
1159
|
shortenAddress,
|
|
970
1160
|
usePaymentLink,
|
|
1161
|
+
usePaymentModal,
|
|
971
1162
|
useSettlr,
|
|
972
1163
|
verifyWebhookSignature
|
|
973
1164
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -499,7 +499,8 @@ function useSettlr() {
|
|
|
499
499
|
// src/components.tsx
|
|
500
500
|
import {
|
|
501
501
|
useState,
|
|
502
|
-
useCallback
|
|
502
|
+
useCallback,
|
|
503
|
+
useEffect
|
|
503
504
|
} from "react";
|
|
504
505
|
import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
505
506
|
var defaultStyles = {
|
|
@@ -856,6 +857,193 @@ function usePaymentLink(config) {
|
|
|
856
857
|
generateQRCode
|
|
857
858
|
};
|
|
858
859
|
}
|
|
860
|
+
var modalStyles = {
|
|
861
|
+
overlay: {
|
|
862
|
+
position: "fixed",
|
|
863
|
+
top: 0,
|
|
864
|
+
left: 0,
|
|
865
|
+
right: 0,
|
|
866
|
+
bottom: 0,
|
|
867
|
+
backgroundColor: "rgba(0, 0, 0, 0.8)",
|
|
868
|
+
backdropFilter: "blur(4px)",
|
|
869
|
+
display: "flex",
|
|
870
|
+
alignItems: "center",
|
|
871
|
+
justifyContent: "center",
|
|
872
|
+
zIndex: 9999,
|
|
873
|
+
padding: "16px"
|
|
874
|
+
},
|
|
875
|
+
container: {
|
|
876
|
+
position: "relative",
|
|
877
|
+
width: "100%",
|
|
878
|
+
maxWidth: "480px",
|
|
879
|
+
height: "90vh",
|
|
880
|
+
maxHeight: "700px",
|
|
881
|
+
backgroundColor: "#12121a",
|
|
882
|
+
borderRadius: "16px",
|
|
883
|
+
overflow: "hidden",
|
|
884
|
+
boxShadow: "0 25px 50px -12px rgba(0, 0, 0, 0.5)"
|
|
885
|
+
},
|
|
886
|
+
closeButton: {
|
|
887
|
+
position: "absolute",
|
|
888
|
+
top: "12px",
|
|
889
|
+
right: "12px",
|
|
890
|
+
width: "32px",
|
|
891
|
+
height: "32px",
|
|
892
|
+
borderRadius: "50%",
|
|
893
|
+
backgroundColor: "rgba(255, 255, 255, 0.1)",
|
|
894
|
+
border: "none",
|
|
895
|
+
cursor: "pointer",
|
|
896
|
+
display: "flex",
|
|
897
|
+
alignItems: "center",
|
|
898
|
+
justifyContent: "center",
|
|
899
|
+
zIndex: 10,
|
|
900
|
+
color: "white",
|
|
901
|
+
fontSize: "18px",
|
|
902
|
+
transition: "background-color 0.2s"
|
|
903
|
+
},
|
|
904
|
+
iframe: {
|
|
905
|
+
width: "100%",
|
|
906
|
+
height: "100%",
|
|
907
|
+
border: "none"
|
|
908
|
+
},
|
|
909
|
+
loading: {
|
|
910
|
+
position: "absolute",
|
|
911
|
+
top: "50%",
|
|
912
|
+
left: "50%",
|
|
913
|
+
transform: "translate(-50%, -50%)",
|
|
914
|
+
color: "white",
|
|
915
|
+
fontSize: "14px",
|
|
916
|
+
display: "flex",
|
|
917
|
+
flexDirection: "column",
|
|
918
|
+
alignItems: "center",
|
|
919
|
+
gap: "12px"
|
|
920
|
+
}
|
|
921
|
+
};
|
|
922
|
+
function PaymentModal({
|
|
923
|
+
amount,
|
|
924
|
+
merchantName,
|
|
925
|
+
merchantWallet,
|
|
926
|
+
memo,
|
|
927
|
+
orderId,
|
|
928
|
+
onSuccess,
|
|
929
|
+
onClose,
|
|
930
|
+
onError,
|
|
931
|
+
checkoutUrl = "https://settlr.dev/checkout"
|
|
932
|
+
}) {
|
|
933
|
+
const [loading, setLoading] = useState(true);
|
|
934
|
+
const params = new URLSearchParams({
|
|
935
|
+
amount: amount.toString(),
|
|
936
|
+
merchant: merchantName,
|
|
937
|
+
to: merchantWallet,
|
|
938
|
+
embed: "true"
|
|
939
|
+
});
|
|
940
|
+
if (memo) params.set("memo", memo);
|
|
941
|
+
if (orderId) params.set("orderId", orderId);
|
|
942
|
+
const iframeSrc = `${checkoutUrl}?${params.toString()}`;
|
|
943
|
+
useEffect(() => {
|
|
944
|
+
const handleMessage = (event) => {
|
|
945
|
+
if (!event.origin.includes("settlr.dev") && !event.origin.includes("localhost")) {
|
|
946
|
+
return;
|
|
947
|
+
}
|
|
948
|
+
const { type, data } = event.data || {};
|
|
949
|
+
switch (type) {
|
|
950
|
+
case "settlr:success":
|
|
951
|
+
onSuccess?.({
|
|
952
|
+
signature: data.signature,
|
|
953
|
+
amount: data.amount || amount
|
|
954
|
+
});
|
|
955
|
+
break;
|
|
956
|
+
case "settlr:error":
|
|
957
|
+
onError?.(new Error(data.message || "Payment failed"));
|
|
958
|
+
break;
|
|
959
|
+
case "settlr:close":
|
|
960
|
+
onClose?.();
|
|
961
|
+
break;
|
|
962
|
+
}
|
|
963
|
+
};
|
|
964
|
+
window.addEventListener("message", handleMessage);
|
|
965
|
+
return () => window.removeEventListener("message", handleMessage);
|
|
966
|
+
}, [amount, onSuccess, onError, onClose]);
|
|
967
|
+
useEffect(() => {
|
|
968
|
+
const handleEscape = (e) => {
|
|
969
|
+
if (e.key === "Escape") onClose?.();
|
|
970
|
+
};
|
|
971
|
+
window.addEventListener("keydown", handleEscape);
|
|
972
|
+
return () => window.removeEventListener("keydown", handleEscape);
|
|
973
|
+
}, [onClose]);
|
|
974
|
+
return /* @__PURE__ */ jsx2("div", { style: modalStyles.overlay, onClick: onClose, children: /* @__PURE__ */ jsxs("div", { style: modalStyles.container, onClick: (e) => e.stopPropagation(), children: [
|
|
975
|
+
/* @__PURE__ */ jsx2(
|
|
976
|
+
"button",
|
|
977
|
+
{
|
|
978
|
+
style: modalStyles.closeButton,
|
|
979
|
+
onClick: onClose,
|
|
980
|
+
onMouseOver: (e) => e.currentTarget.style.backgroundColor = "rgba(255, 255, 255, 0.2)",
|
|
981
|
+
onMouseOut: (e) => e.currentTarget.style.backgroundColor = "rgba(255, 255, 255, 0.1)",
|
|
982
|
+
children: "\u2715"
|
|
983
|
+
}
|
|
984
|
+
),
|
|
985
|
+
loading && /* @__PURE__ */ jsxs("div", { style: modalStyles.loading, children: [
|
|
986
|
+
/* @__PURE__ */ jsx2(Spinner, {}),
|
|
987
|
+
/* @__PURE__ */ jsx2("span", { children: "Loading checkout..." })
|
|
988
|
+
] }),
|
|
989
|
+
/* @__PURE__ */ jsx2(
|
|
990
|
+
"iframe",
|
|
991
|
+
{
|
|
992
|
+
src: iframeSrc,
|
|
993
|
+
style: {
|
|
994
|
+
...modalStyles.iframe,
|
|
995
|
+
opacity: loading ? 0 : 1
|
|
996
|
+
},
|
|
997
|
+
onLoad: () => setLoading(false),
|
|
998
|
+
allow: "payment"
|
|
999
|
+
}
|
|
1000
|
+
)
|
|
1001
|
+
] }) });
|
|
1002
|
+
}
|
|
1003
|
+
function usePaymentModal(config) {
|
|
1004
|
+
const [modalState, setModalState] = useState({
|
|
1005
|
+
isOpen: false,
|
|
1006
|
+
amount: 0
|
|
1007
|
+
});
|
|
1008
|
+
const openPayment = useCallback(
|
|
1009
|
+
(options) => {
|
|
1010
|
+
setModalState({
|
|
1011
|
+
isOpen: true,
|
|
1012
|
+
...options
|
|
1013
|
+
});
|
|
1014
|
+
},
|
|
1015
|
+
[]
|
|
1016
|
+
);
|
|
1017
|
+
const closePayment = useCallback(() => {
|
|
1018
|
+
setModalState((prev) => ({ ...prev, isOpen: false }));
|
|
1019
|
+
}, []);
|
|
1020
|
+
const PaymentModalComponent = useCallback(() => {
|
|
1021
|
+
if (!modalState.isOpen) return null;
|
|
1022
|
+
return /* @__PURE__ */ jsx2(
|
|
1023
|
+
PaymentModal,
|
|
1024
|
+
{
|
|
1025
|
+
amount: modalState.amount,
|
|
1026
|
+
merchantName: config.merchantName,
|
|
1027
|
+
merchantWallet: config.merchantWallet,
|
|
1028
|
+
memo: modalState.memo,
|
|
1029
|
+
orderId: modalState.orderId,
|
|
1030
|
+
checkoutUrl: config.checkoutUrl,
|
|
1031
|
+
onSuccess: (result) => {
|
|
1032
|
+
modalState.onSuccess?.(result);
|
|
1033
|
+
closePayment();
|
|
1034
|
+
},
|
|
1035
|
+
onError: modalState.onError,
|
|
1036
|
+
onClose: closePayment
|
|
1037
|
+
}
|
|
1038
|
+
);
|
|
1039
|
+
}, [modalState, config, closePayment]);
|
|
1040
|
+
return {
|
|
1041
|
+
openPayment,
|
|
1042
|
+
closePayment,
|
|
1043
|
+
isOpen: modalState.isOpen,
|
|
1044
|
+
PaymentModalComponent
|
|
1045
|
+
};
|
|
1046
|
+
}
|
|
859
1047
|
|
|
860
1048
|
// src/webhooks.ts
|
|
861
1049
|
import crypto from "crypto";
|
|
@@ -918,6 +1106,7 @@ function createWebhookHandler(options) {
|
|
|
918
1106
|
export {
|
|
919
1107
|
BuyButton,
|
|
920
1108
|
CheckoutWidget,
|
|
1109
|
+
PaymentModal,
|
|
921
1110
|
SETTLR_CHECKOUT_URL,
|
|
922
1111
|
SUPPORTED_NETWORKS,
|
|
923
1112
|
Settlr,
|
|
@@ -930,6 +1119,7 @@ export {
|
|
|
930
1119
|
parseWebhookPayload,
|
|
931
1120
|
shortenAddress,
|
|
932
1121
|
usePaymentLink,
|
|
1122
|
+
usePaymentModal,
|
|
933
1123
|
useSettlr,
|
|
934
1124
|
verifyWebhookSignature
|
|
935
1125
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@settlr/sdk",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Solana USDC payments
|
|
3
|
+
"version": "0.3.1",
|
|
4
|
+
"description": "Settlr SDK - Accept Solana USDC payments in games and apps. Email checkout, gasless transactions, no wallet required. The easiest way to add crypto payments.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -24,21 +24,45 @@
|
|
|
24
24
|
"prepublishOnly": "npm run build"
|
|
25
25
|
},
|
|
26
26
|
"keywords": [
|
|
27
|
+
"settlr",
|
|
28
|
+
"settlr-sdk",
|
|
29
|
+
"settlr.dev",
|
|
27
30
|
"solana",
|
|
28
|
-
"payments",
|
|
31
|
+
"solana-payments",
|
|
29
32
|
"usdc",
|
|
30
|
-
"
|
|
33
|
+
"usdc-payments",
|
|
34
|
+
"crypto-payments",
|
|
31
35
|
"web3",
|
|
36
|
+
"web3-payments",
|
|
32
37
|
"stablecoin",
|
|
33
|
-
"gasless"
|
|
38
|
+
"gasless",
|
|
39
|
+
"gasless-transactions",
|
|
40
|
+
"payment-gateway",
|
|
41
|
+
"checkout",
|
|
42
|
+
"gaming-payments",
|
|
43
|
+
"game-monetization",
|
|
44
|
+
"in-app-purchases",
|
|
45
|
+
"react",
|
|
46
|
+
"typescript",
|
|
47
|
+
"email-checkout",
|
|
48
|
+
"no-wallet",
|
|
49
|
+
"privy"
|
|
34
50
|
],
|
|
35
|
-
"author": "Settlr",
|
|
51
|
+
"author": "Settlr <hello@settlr.dev> (https://settlr.dev)",
|
|
36
52
|
"license": "MIT",
|
|
37
53
|
"repository": {
|
|
38
54
|
"type": "git",
|
|
39
|
-
"url": "git+https://github.com/ABFX15/x402-hack-payment.git"
|
|
55
|
+
"url": "git+https://github.com/ABFX15/x402-hack-payment.git",
|
|
56
|
+
"directory": "packages/sdk"
|
|
57
|
+
},
|
|
58
|
+
"bugs": {
|
|
59
|
+
"url": "https://github.com/ABFX15/x402-hack-payment/issues"
|
|
40
60
|
},
|
|
41
61
|
"homepage": "https://settlr.dev",
|
|
62
|
+
"funding": {
|
|
63
|
+
"type": "github",
|
|
64
|
+
"url": "https://github.com/sponsors/ABFX15"
|
|
65
|
+
},
|
|
42
66
|
"dependencies": {
|
|
43
67
|
"@solana/spl-token": "^0.4.13",
|
|
44
68
|
"@solana/web3.js": "^1.98.0"
|