@settlr/sdk 0.1.0 → 0.3.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/README.md +33 -69
- package/dist/index.d.mts +174 -34
- package/dist/index.d.ts +174 -34
- package/dist/index.js +252 -62
- package/dist/index.mjs +252 -63
- package/package.json +5 -6
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
|
});
|
|
@@ -62,8 +64,8 @@ var SETTLR_API_URL = {
|
|
|
62
64
|
development: "http://localhost:3000/api"
|
|
63
65
|
};
|
|
64
66
|
var SETTLR_CHECKOUT_URL = {
|
|
65
|
-
production: "https://settlr.dev/
|
|
66
|
-
development: "http://localhost:3000/
|
|
67
|
+
production: "https://settlr.dev/checkout",
|
|
68
|
+
development: "http://localhost:3000/checkout"
|
|
67
69
|
};
|
|
68
70
|
var SUPPORTED_NETWORKS = ["devnet", "mainnet-beta"];
|
|
69
71
|
var USDC_DECIMALS = 6;
|
|
@@ -188,6 +190,37 @@ var Settlr = class {
|
|
|
188
190
|
getTier() {
|
|
189
191
|
return this.tier;
|
|
190
192
|
}
|
|
193
|
+
/**
|
|
194
|
+
* Get a checkout URL for redirect-based payments
|
|
195
|
+
*
|
|
196
|
+
* This is the simplest integration - just redirect users to this URL.
|
|
197
|
+
* Settlr handles auth (email or wallet) and payment processing.
|
|
198
|
+
*
|
|
199
|
+
* @example
|
|
200
|
+
* ```typescript
|
|
201
|
+
* const url = settlr.getCheckoutUrl({
|
|
202
|
+
* amount: 29.99,
|
|
203
|
+
* memo: 'Premium Pack',
|
|
204
|
+
* });
|
|
205
|
+
*
|
|
206
|
+
* // Redirect user to checkout
|
|
207
|
+
* window.location.href = url;
|
|
208
|
+
* ```
|
|
209
|
+
*/
|
|
210
|
+
getCheckoutUrl(options) {
|
|
211
|
+
const { amount, memo, orderId, successUrl, cancelUrl } = options;
|
|
212
|
+
const baseUrl = this.config.testMode ? SETTLR_CHECKOUT_URL.development : SETTLR_CHECKOUT_URL.production;
|
|
213
|
+
const params = new URLSearchParams({
|
|
214
|
+
amount: amount.toString(),
|
|
215
|
+
merchant: this.config.merchant.name,
|
|
216
|
+
to: this.config.merchant.walletAddress
|
|
217
|
+
});
|
|
218
|
+
if (memo) params.set("memo", memo);
|
|
219
|
+
if (orderId) params.set("orderId", orderId);
|
|
220
|
+
if (successUrl) params.set("successUrl", successUrl);
|
|
221
|
+
if (cancelUrl) params.set("cancelUrl", cancelUrl);
|
|
222
|
+
return `${baseUrl}?${params.toString()}`;
|
|
223
|
+
}
|
|
191
224
|
/**
|
|
192
225
|
* Create a payment link
|
|
193
226
|
*
|
|
@@ -221,8 +254,8 @@ var Settlr = class {
|
|
|
221
254
|
});
|
|
222
255
|
if (memo) params.set("memo", memo);
|
|
223
256
|
if (orderId) params.set("orderId", orderId);
|
|
224
|
-
if (successUrl) params.set("
|
|
225
|
-
if (cancelUrl) params.set("
|
|
257
|
+
if (successUrl) params.set("success", successUrl);
|
|
258
|
+
if (cancelUrl) params.set("cancel", cancelUrl);
|
|
226
259
|
if (paymentId) params.set("paymentId", paymentId);
|
|
227
260
|
const checkoutUrl = `${baseUrl}?${params.toString()}`;
|
|
228
261
|
const qrCode = await this.generateQRCode(checkoutUrl);
|
|
@@ -466,49 +499,34 @@ var Settlr = class {
|
|
|
466
499
|
|
|
467
500
|
// src/react.tsx
|
|
468
501
|
var import_react = require("react");
|
|
469
|
-
var import_wallet_adapter_react = require("@solana/wallet-adapter-react");
|
|
470
502
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
471
503
|
var SettlrContext = (0, import_react.createContext)(null);
|
|
472
|
-
function SettlrProvider({
|
|
473
|
-
|
|
474
|
-
|
|
504
|
+
function SettlrProvider({
|
|
505
|
+
children,
|
|
506
|
+
config,
|
|
507
|
+
authenticated = false
|
|
508
|
+
}) {
|
|
475
509
|
const settlr = (0, import_react.useMemo)(() => {
|
|
476
510
|
return new Settlr({
|
|
477
511
|
...config,
|
|
478
|
-
rpcEndpoint:
|
|
512
|
+
rpcEndpoint: config.rpcEndpoint ?? "https://api.devnet.solana.com"
|
|
479
513
|
});
|
|
480
|
-
}, [config
|
|
514
|
+
}, [config]);
|
|
481
515
|
const value = (0, import_react.useMemo)(
|
|
482
516
|
() => ({
|
|
483
517
|
settlr,
|
|
484
|
-
|
|
518
|
+
authenticated,
|
|
485
519
|
createPayment: (options) => {
|
|
486
520
|
return settlr.createPayment(options);
|
|
487
521
|
},
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
return {
|
|
491
|
-
success: false,
|
|
492
|
-
signature: "",
|
|
493
|
-
amount: options.amount,
|
|
494
|
-
merchantAddress: settlr.getMerchantAddress().toBase58(),
|
|
495
|
-
error: "Wallet not connected"
|
|
496
|
-
};
|
|
497
|
-
}
|
|
498
|
-
return settlr.pay({
|
|
499
|
-
wallet: {
|
|
500
|
-
publicKey: wallet.publicKey,
|
|
501
|
-
signTransaction: wallet.signTransaction
|
|
502
|
-
},
|
|
503
|
-
amount: options.amount,
|
|
504
|
-
memo: options.memo
|
|
505
|
-
});
|
|
522
|
+
getCheckoutUrl: (options) => {
|
|
523
|
+
return settlr.getCheckoutUrl(options);
|
|
506
524
|
},
|
|
507
525
|
getBalance: () => {
|
|
508
526
|
return settlr.getMerchantBalance();
|
|
509
527
|
}
|
|
510
528
|
}),
|
|
511
|
-
[settlr,
|
|
529
|
+
[settlr, authenticated]
|
|
512
530
|
);
|
|
513
531
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SettlrContext.Provider, { value, children });
|
|
514
532
|
}
|
|
@@ -578,7 +596,8 @@ function BuyButton({
|
|
|
578
596
|
onSuccess,
|
|
579
597
|
onError,
|
|
580
598
|
onProcessing,
|
|
581
|
-
useRedirect =
|
|
599
|
+
useRedirect = true,
|
|
600
|
+
// Default to redirect flow (works with Privy)
|
|
582
601
|
successUrl,
|
|
583
602
|
cancelUrl,
|
|
584
603
|
className,
|
|
@@ -587,7 +606,7 @@ function BuyButton({
|
|
|
587
606
|
variant = "primary",
|
|
588
607
|
size = "md"
|
|
589
608
|
}) {
|
|
590
|
-
const {
|
|
609
|
+
const { getCheckoutUrl, createPayment } = useSettlr();
|
|
591
610
|
const [loading, setLoading] = (0, import_react2.useState)(false);
|
|
592
611
|
const [status, setStatus] = (0, import_react2.useState)("idle");
|
|
593
612
|
const handleClick = (0, import_react2.useCallback)(async () => {
|
|
@@ -596,32 +615,17 @@ function BuyButton({
|
|
|
596
615
|
setStatus("processing");
|
|
597
616
|
onProcessing?.();
|
|
598
617
|
try {
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
window.location.href = payment.checkoutUrl;
|
|
608
|
-
} else {
|
|
609
|
-
const result = await pay({ amount, memo });
|
|
610
|
-
if (result.success) {
|
|
611
|
-
setStatus("success");
|
|
612
|
-
onSuccess?.({
|
|
613
|
-
signature: result.signature,
|
|
614
|
-
amount: result.amount,
|
|
615
|
-
merchantAddress: result.merchantAddress
|
|
616
|
-
});
|
|
617
|
-
} else {
|
|
618
|
-
throw new Error(result.error || "Payment failed");
|
|
619
|
-
}
|
|
620
|
-
}
|
|
618
|
+
const url = getCheckoutUrl({
|
|
619
|
+
amount,
|
|
620
|
+
memo,
|
|
621
|
+
orderId,
|
|
622
|
+
successUrl,
|
|
623
|
+
cancelUrl
|
|
624
|
+
});
|
|
625
|
+
window.location.href = url;
|
|
621
626
|
} catch (error) {
|
|
622
627
|
setStatus("error");
|
|
623
628
|
onError?.(error instanceof Error ? error : new Error("Payment failed"));
|
|
624
|
-
} finally {
|
|
625
629
|
setLoading(false);
|
|
626
630
|
}
|
|
627
631
|
}, [
|
|
@@ -630,12 +634,9 @@ function BuyButton({
|
|
|
630
634
|
orderId,
|
|
631
635
|
disabled,
|
|
632
636
|
loading,
|
|
633
|
-
useRedirect,
|
|
634
637
|
successUrl,
|
|
635
638
|
cancelUrl,
|
|
636
|
-
|
|
637
|
-
createPayment,
|
|
638
|
-
onSuccess,
|
|
639
|
+
getCheckoutUrl,
|
|
639
640
|
onError,
|
|
640
641
|
onProcessing
|
|
641
642
|
]);
|
|
@@ -655,11 +656,11 @@ function BuyButton({
|
|
|
655
656
|
"button",
|
|
656
657
|
{
|
|
657
658
|
onClick: handleClick,
|
|
658
|
-
disabled: disabled || loading
|
|
659
|
+
disabled: disabled || loading,
|
|
659
660
|
className,
|
|
660
661
|
style: buttonStyle,
|
|
661
662
|
type: "button",
|
|
662
|
-
children:
|
|
663
|
+
children: buttonContent
|
|
663
664
|
}
|
|
664
665
|
);
|
|
665
666
|
}
|
|
@@ -783,7 +784,7 @@ function CheckoutWidget({
|
|
|
783
784
|
theme = "dark",
|
|
784
785
|
showBranding = true
|
|
785
786
|
}) {
|
|
786
|
-
const {
|
|
787
|
+
const { getCheckoutUrl } = useSettlr();
|
|
787
788
|
const [status, setStatus] = (0, import_react2.useState)("idle");
|
|
788
789
|
const containerStyle = {
|
|
789
790
|
...widgetStyles.container,
|
|
@@ -894,6 +895,193 @@ function usePaymentLink(config) {
|
|
|
894
895
|
generateQRCode
|
|
895
896
|
};
|
|
896
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
|
+
}
|
|
897
1085
|
|
|
898
1086
|
// src/webhooks.ts
|
|
899
1087
|
var import_crypto = __toESM(require("crypto"));
|
|
@@ -957,6 +1145,7 @@ function createWebhookHandler(options) {
|
|
|
957
1145
|
0 && (module.exports = {
|
|
958
1146
|
BuyButton,
|
|
959
1147
|
CheckoutWidget,
|
|
1148
|
+
PaymentModal,
|
|
960
1149
|
SETTLR_CHECKOUT_URL,
|
|
961
1150
|
SUPPORTED_NETWORKS,
|
|
962
1151
|
Settlr,
|
|
@@ -969,6 +1158,7 @@ function createWebhookHandler(options) {
|
|
|
969
1158
|
parseWebhookPayload,
|
|
970
1159
|
shortenAddress,
|
|
971
1160
|
usePaymentLink,
|
|
1161
|
+
usePaymentModal,
|
|
972
1162
|
useSettlr,
|
|
973
1163
|
verifyWebhookSignature
|
|
974
1164
|
});
|