@superlogic/spree-pay 0.1.4 → 0.1.6
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 -2
- package/build/index.cjs +338 -124
- package/build/index.d.cts +27 -6
- package/build/index.d.ts +27 -6
- package/build/index.js +329 -115
- package/package.json +4 -3
package/build/index.js
CHANGED
|
@@ -5609,7 +5609,8 @@ var cardPayment = async ({ card, hash, redirect3dsURI }) => {
|
|
|
5609
5609
|
}
|
|
5610
5610
|
}
|
|
5611
5611
|
return {
|
|
5612
|
-
status: paymentResData.status
|
|
5612
|
+
status: paymentResData.status,
|
|
5613
|
+
paymentId: paymentResData.id
|
|
5613
5614
|
};
|
|
5614
5615
|
};
|
|
5615
5616
|
|
|
@@ -6602,33 +6603,173 @@ var CreditCardTab = () => {
|
|
|
6602
6603
|
// src/components/CryptoTab/Crypto/CryptoWrapper.tsx
|
|
6603
6604
|
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
6604
6605
|
import NiceModal5 from "@ebay/nice-modal-react";
|
|
6605
|
-
import { RainbowKitProvider,
|
|
6606
|
+
import { RainbowKitProvider, connectorsForWallets } from "@rainbow-me/rainbowkit";
|
|
6606
6607
|
import "@rainbow-me/rainbowkit/styles.css";
|
|
6607
|
-
import {
|
|
6608
|
+
import { injectedWallet, walletConnectWallet } from "@rainbow-me/rainbowkit/wallets";
|
|
6609
|
+
import { WagmiProvider, createConfig, http as http2 } from "wagmi";
|
|
6608
6610
|
import { base } from "wagmi/chains";
|
|
6609
6611
|
|
|
6610
6612
|
// src/components/CryptoTab/Crypto/Crypto.tsx
|
|
6611
6613
|
import { useCallback as useCallback9, useEffect as useEffect19 } from "react";
|
|
6612
|
-
import { useAccount as useAccount3
|
|
6614
|
+
import { useAccount as useAccount3 } from "wagmi";
|
|
6613
6615
|
|
|
6614
|
-
//
|
|
6615
|
-
|
|
6616
|
-
const
|
|
6617
|
-
|
|
6618
|
-
|
|
6619
|
-
|
|
6620
|
-
|
|
6621
|
-
|
|
6622
|
-
|
|
6623
|
-
|
|
6624
|
-
|
|
6616
|
+
// ../../node_modules/@wagmi/core/dist/esm/utils/getAction.js
|
|
6617
|
+
function getAction(client, actionFn, name) {
|
|
6618
|
+
const action_implicit = client[actionFn.name];
|
|
6619
|
+
if (typeof action_implicit === "function")
|
|
6620
|
+
return action_implicit;
|
|
6621
|
+
const action_explicit = client[name];
|
|
6622
|
+
if (typeof action_explicit === "function")
|
|
6623
|
+
return action_explicit;
|
|
6624
|
+
return (params) => actionFn(client, params);
|
|
6625
|
+
}
|
|
6626
|
+
|
|
6627
|
+
// ../../node_modules/@wagmi/core/dist/esm/actions/readContract.js
|
|
6628
|
+
import { readContract as viem_readContract } from "viem/actions";
|
|
6629
|
+
function readContract(config2, parameters) {
|
|
6630
|
+
const { chainId, ...rest } = parameters;
|
|
6631
|
+
const client = config2.getClient({ chainId });
|
|
6632
|
+
const action = getAction(client, viem_readContract, "readContract");
|
|
6633
|
+
return action(rest);
|
|
6634
|
+
}
|
|
6635
|
+
|
|
6636
|
+
// ../../node_modules/@wagmi/core/dist/esm/actions/waitForTransactionReceipt.js
|
|
6637
|
+
import { hexToString } from "viem";
|
|
6638
|
+
import { call, getTransaction, waitForTransactionReceipt as viem_waitForTransactionReceipt } from "viem/actions";
|
|
6639
|
+
async function waitForTransactionReceipt(config2, parameters) {
|
|
6640
|
+
const { chainId, timeout = 0, ...rest } = parameters;
|
|
6641
|
+
const client = config2.getClient({ chainId });
|
|
6642
|
+
const action = getAction(client, viem_waitForTransactionReceipt, "waitForTransactionReceipt");
|
|
6643
|
+
const receipt = await action({ ...rest, timeout });
|
|
6644
|
+
if (receipt.status === "reverted") {
|
|
6645
|
+
const action_getTransaction = getAction(client, getTransaction, "getTransaction");
|
|
6646
|
+
const txn = await action_getTransaction({ hash: receipt.transactionHash });
|
|
6647
|
+
const action_call = getAction(client, call, "call");
|
|
6648
|
+
const code = await action_call({
|
|
6649
|
+
...txn,
|
|
6650
|
+
data: txn.input,
|
|
6651
|
+
gasPrice: txn.type !== "eip1559" ? txn.gasPrice : void 0,
|
|
6652
|
+
maxFeePerGas: txn.type === "eip1559" ? txn.maxFeePerGas : void 0,
|
|
6653
|
+
maxPriorityFeePerGas: txn.type === "eip1559" ? txn.maxPriorityFeePerGas : void 0
|
|
6654
|
+
});
|
|
6655
|
+
const reason = code?.data ? hexToString(`0x${code.data.substring(138)}`) : "unknown reason";
|
|
6656
|
+
throw new Error(reason);
|
|
6657
|
+
}
|
|
6658
|
+
return {
|
|
6659
|
+
...receipt,
|
|
6660
|
+
chainId: client.chain.id
|
|
6661
|
+
};
|
|
6662
|
+
}
|
|
6663
|
+
|
|
6664
|
+
// ../../node_modules/@wagmi/core/dist/esm/exports/index.js
|
|
6665
|
+
import { custom, http, webSocket } from "viem";
|
|
6666
|
+
|
|
6667
|
+
// src/hooks/useCryptoPayment.ts
|
|
6668
|
+
import { erc20Abi } from "viem";
|
|
6669
|
+
import { useConfig as useConfig2, useWalletClient } from "wagmi";
|
|
6670
|
+
|
|
6671
|
+
// src/config/baseTokens.ts
|
|
6672
|
+
var BASE_CHAIN_ID = 8453;
|
|
6673
|
+
var BASE_TOKENS = [
|
|
6674
|
+
{
|
|
6675
|
+
address: "0x2b11834ed1feaed4b4b3a86a6f571315e25a884d",
|
|
6676
|
+
chainId: BASE_CHAIN_ID,
|
|
6677
|
+
decimals: 18,
|
|
6678
|
+
symbol: "MOCA" /* MOCA */,
|
|
6679
|
+
name: "Moca",
|
|
6680
|
+
logoURI: "https://assets.coingecko.com/coins/images/30046/standard/moca.png"
|
|
6681
|
+
},
|
|
6682
|
+
{
|
|
6683
|
+
address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bDA02913",
|
|
6684
|
+
chainId: BASE_CHAIN_ID,
|
|
6685
|
+
decimals: 6,
|
|
6686
|
+
symbol: "USDC" /* USDC */,
|
|
6687
|
+
name: "USD Coin",
|
|
6688
|
+
logoURI: "https://cryptologos.cc/logos/usd-coin-usdc-logo.png"
|
|
6689
|
+
},
|
|
6690
|
+
{
|
|
6691
|
+
address: "0x4200000000000000000000000000000000000006",
|
|
6692
|
+
chainId: BASE_CHAIN_ID,
|
|
6693
|
+
decimals: 18,
|
|
6694
|
+
symbol: "WETH" /* WETH */,
|
|
6695
|
+
name: "Wrapped Ether",
|
|
6696
|
+
logoURI: "https://static.cdnlogo.com/logos/e/84/ethereum-eth_thumb.png"
|
|
6697
|
+
},
|
|
6698
|
+
{
|
|
6699
|
+
address: "0xfde4c96c8593536e31f229ea8f37b2ada2699bb2",
|
|
6700
|
+
chainId: BASE_CHAIN_ID,
|
|
6701
|
+
decimals: 6,
|
|
6702
|
+
symbol: "USDT" /* USDT */,
|
|
6703
|
+
name: "Tether USD",
|
|
6704
|
+
logoURI: "https://cryptologos.cc/logos/tether-usdt-logo.png"
|
|
6705
|
+
}
|
|
6706
|
+
];
|
|
6707
|
+
|
|
6708
|
+
// src/hooks/useCryptoPayment.ts
|
|
6709
|
+
var MAX_UINT256 = BigInt(2) ** BigInt(256) - BigInt(1);
|
|
6710
|
+
var ONE_INCH_AGGREGATION_ROUTER_V6 = "0x111111125421ca6dc452d289314280a0f8842a65";
|
|
6711
|
+
var useCryptoPayment = () => {
|
|
6712
|
+
const { data: walletClient } = useWalletClient();
|
|
6713
|
+
const config2 = useConfig2();
|
|
6714
|
+
const { selectedPaymentMethod } = useSpreePaymentMethod();
|
|
6715
|
+
const cryptoPayment = async ({ hash }) => {
|
|
6716
|
+
if (!walletClient) {
|
|
6717
|
+
throw new Error("Wallet not connected");
|
|
6625
6718
|
}
|
|
6626
|
-
|
|
6627
|
-
|
|
6628
|
-
|
|
6629
|
-
|
|
6630
|
-
|
|
6631
|
-
|
|
6719
|
+
if (selectedPaymentMethod.type !== "CRYPTO" /* CRYPTO */ || !selectedPaymentMethod.method?.symbol) {
|
|
6720
|
+
throw new Error("Unsupported payment method");
|
|
6721
|
+
}
|
|
6722
|
+
const TOKEN = selectedPaymentMethod.method.symbol;
|
|
6723
|
+
if (["MOCA" /* MOCA */, "WETH" /* WETH */, "USDC" /* USDC */, "USDT" /* USDT */].includes(TOKEN)) {
|
|
6724
|
+
const tokenAddress = selectedPaymentMethod.method.address;
|
|
6725
|
+
if (!tokenAddress) {
|
|
6726
|
+
throw new Error("Token address not found");
|
|
6727
|
+
}
|
|
6728
|
+
const allowance = await readContract(config2, {
|
|
6729
|
+
address: tokenAddress,
|
|
6730
|
+
abi: erc20Abi,
|
|
6731
|
+
functionName: "allowance",
|
|
6732
|
+
args: [walletClient.account.address, ONE_INCH_AGGREGATION_ROUTER_V6]
|
|
6733
|
+
});
|
|
6734
|
+
if (allowance <= 0n) {
|
|
6735
|
+
const result = await walletClient.writeContract({
|
|
6736
|
+
address: tokenAddress,
|
|
6737
|
+
abi: erc20Abi,
|
|
6738
|
+
functionName: "approve",
|
|
6739
|
+
args: [ONE_INCH_AGGREGATION_ROUTER_V6, MAX_UINT256]
|
|
6740
|
+
});
|
|
6741
|
+
await waitForTransactionReceipt(config2, {
|
|
6742
|
+
hash: result,
|
|
6743
|
+
confirmations: 1
|
|
6744
|
+
// You can change the number of block confirmations as per your requirement
|
|
6745
|
+
});
|
|
6746
|
+
}
|
|
6747
|
+
}
|
|
6748
|
+
const paymentRes = await SlapiPaymentService.createPayment({
|
|
6749
|
+
type: "CRYPTO" /* CRYPTO */,
|
|
6750
|
+
hash,
|
|
6751
|
+
crypto: {
|
|
6752
|
+
token: TOKEN,
|
|
6753
|
+
publicKey: walletClient.account.address,
|
|
6754
|
+
slippageType: "fixed",
|
|
6755
|
+
slippageBps: 0.5 * 100
|
|
6756
|
+
}
|
|
6757
|
+
});
|
|
6758
|
+
const parsedTX = JSON.parse(paymentRes.data.encodedTx);
|
|
6759
|
+
const txHash = await walletClient.sendTransaction({
|
|
6760
|
+
account: walletClient.account.address,
|
|
6761
|
+
to: parsedTX.to,
|
|
6762
|
+
data: parsedTX.data,
|
|
6763
|
+
value: parsedTX.value
|
|
6764
|
+
});
|
|
6765
|
+
const res = await SlapiPaymentService.baseVerify({ id: paymentRes.data.txId, txHash });
|
|
6766
|
+
return {
|
|
6767
|
+
txHash,
|
|
6768
|
+
paymentId: paymentRes.data.txId,
|
|
6769
|
+
status: res.verified ? "AUTHORIZED" /* AUTHORIZED */ : "FAILED" /* FAILED */
|
|
6770
|
+
};
|
|
6771
|
+
};
|
|
6772
|
+
return { cryptoPayment };
|
|
6632
6773
|
};
|
|
6633
6774
|
|
|
6634
6775
|
// src/components/CryptoTab/Crypto/ConnectButton.tsx
|
|
@@ -6791,49 +6932,11 @@ import NiceModal3, { useModal as useModal2 } from "@ebay/nice-modal-react";
|
|
|
6791
6932
|
|
|
6792
6933
|
// src/hooks/useBaseERC20Token.ts
|
|
6793
6934
|
import * as React30 from "react";
|
|
6794
|
-
import { erc20Abi, formatUnits, getAddress } from "viem";
|
|
6935
|
+
import { erc20Abi as erc20Abi2, formatUnits, getAddress } from "viem";
|
|
6795
6936
|
import { useAccount, usePublicClient } from "wagmi";
|
|
6796
|
-
|
|
6797
|
-
// src/config/baseTokens.ts
|
|
6798
|
-
var BASE_TOKENS = [
|
|
6799
|
-
{
|
|
6800
|
-
address: "0x2b11834ed1feaed4b4b3a86a6f571315e25a884d",
|
|
6801
|
-
chainId: 8453,
|
|
6802
|
-
decimals: 18,
|
|
6803
|
-
symbol: "MOCA",
|
|
6804
|
-
name: "Moca",
|
|
6805
|
-
logoURI: "https://assets.coingecko.com/coins/images/30046/standard/moca.png"
|
|
6806
|
-
},
|
|
6807
|
-
{
|
|
6808
|
-
address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bDA02913",
|
|
6809
|
-
chainId: 8453,
|
|
6810
|
-
decimals: 6,
|
|
6811
|
-
symbol: "USDC",
|
|
6812
|
-
name: "USD Coin",
|
|
6813
|
-
logoURI: "https://cryptologos.cc/logos/usd-coin-usdc-logo.png"
|
|
6814
|
-
},
|
|
6815
|
-
{
|
|
6816
|
-
address: "0x4200000000000000000000000000000000000006",
|
|
6817
|
-
chainId: 8453,
|
|
6818
|
-
decimals: 18,
|
|
6819
|
-
symbol: "WETH",
|
|
6820
|
-
name: "Wrapped Ether",
|
|
6821
|
-
logoURI: "https://static.cdnlogo.com/logos/e/84/ethereum-eth_thumb.png"
|
|
6822
|
-
},
|
|
6823
|
-
{
|
|
6824
|
-
address: "0xfde4c96c8593536e31f229ea8f37b2ada2699bb2",
|
|
6825
|
-
chainId: 8453,
|
|
6826
|
-
decimals: 6,
|
|
6827
|
-
symbol: "USDT",
|
|
6828
|
-
name: "Tether USD",
|
|
6829
|
-
logoURI: "https://cryptologos.cc/logos/tether-usdt-logo.png"
|
|
6830
|
-
}
|
|
6831
|
-
];
|
|
6832
|
-
|
|
6833
|
-
// src/hooks/useBaseERC20Token.ts
|
|
6834
6937
|
function useBaseERC20Token() {
|
|
6835
6938
|
const { address } = useAccount();
|
|
6836
|
-
const baseClient = usePublicClient({ chainId:
|
|
6939
|
+
const baseClient = usePublicClient({ chainId: BASE_CHAIN_ID });
|
|
6837
6940
|
const defaultClient = usePublicClient();
|
|
6838
6941
|
const [rows, setRows] = React30.useState([]);
|
|
6839
6942
|
const [isLoading, setLoading] = React30.useState(false);
|
|
@@ -6860,7 +6963,7 @@ function useBaseERC20Token() {
|
|
|
6860
6963
|
allowFailure: true,
|
|
6861
6964
|
contracts: normalizedTokens.map((t) => ({
|
|
6862
6965
|
address: t.address,
|
|
6863
|
-
abi:
|
|
6966
|
+
abi: erc20Abi2,
|
|
6864
6967
|
functionName: "balanceOf",
|
|
6865
6968
|
args: [address]
|
|
6866
6969
|
}))
|
|
@@ -6878,7 +6981,9 @@ function useBaseERC20Token() {
|
|
|
6878
6981
|
} catch (e) {
|
|
6879
6982
|
if (!cancelled) {
|
|
6880
6983
|
const msg = e instanceof Error ? e.message : "Multicall failed";
|
|
6881
|
-
setError(
|
|
6984
|
+
setError(
|
|
6985
|
+
baseClient ? msg : `Base client unavailable. Ensure Base (${BASE_CHAIN_ID}) is configured in Wagmi.`
|
|
6986
|
+
);
|
|
6882
6987
|
}
|
|
6883
6988
|
} finally {
|
|
6884
6989
|
if (!cancelled) setLoading(false);
|
|
@@ -6898,11 +7003,10 @@ function useBaseNativeToken() {
|
|
|
6898
7003
|
const { address } = useAccount2();
|
|
6899
7004
|
const { data, isLoading, error } = useBalance({
|
|
6900
7005
|
address,
|
|
6901
|
-
chainId:
|
|
6902
|
-
// Base
|
|
7006
|
+
chainId: BASE_CHAIN_ID,
|
|
6903
7007
|
query: { enabled: !!address }
|
|
6904
7008
|
});
|
|
6905
|
-
const nativeBalance = data ? { ...data, logoURI: "https://static.cdnlogo.com/logos/e/84/ethereum-eth_thumb.png" } : void 0;
|
|
7009
|
+
const nativeBalance = data ? { ...data, symbol: "ETH" /* ETH */, logoURI: "https://static.cdnlogo.com/logos/e/84/ethereum-eth_thumb.png" } : void 0;
|
|
6906
7010
|
return {
|
|
6907
7011
|
isLoadingNative: isLoading,
|
|
6908
7012
|
nativeError: error?.message ?? null,
|
|
@@ -6970,7 +7074,6 @@ var CryptoSelectModal = NiceModal3.create(() => {
|
|
|
6970
7074
|
return /* @__PURE__ */ jsxs16(
|
|
6971
7075
|
"button",
|
|
6972
7076
|
{
|
|
6973
|
-
disabled: true,
|
|
6974
7077
|
className: "flex h-11 w-full items-center justify-between gap-4 rounded-sm px-1.5 hover:bg-gray-100 disabled:cursor-not-allowed disabled:opacity-50",
|
|
6975
7078
|
onClick: () => handleSelect(coin),
|
|
6976
7079
|
children: [
|
|
@@ -7031,40 +7134,23 @@ var SelectedCoin = (props) => {
|
|
|
7031
7134
|
import { jsx as jsx31, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
7032
7135
|
var Crypto = () => {
|
|
7033
7136
|
const { address } = useAccount3();
|
|
7034
|
-
const { data: walletClient } = useWalletClient();
|
|
7035
7137
|
const { selectedPaymentMethod } = useSpreePaymentMethod();
|
|
7138
|
+
const { cryptoPayment } = useCryptoPayment();
|
|
7036
7139
|
const isWalletConnected = Boolean(address);
|
|
7037
7140
|
const { register } = useSpreePayRegister();
|
|
7038
7141
|
const handlePay = useCallback9(
|
|
7039
7142
|
async (data) => {
|
|
7040
7143
|
try {
|
|
7041
|
-
|
|
7042
|
-
|
|
7043
|
-
|
|
7044
|
-
return walletClient.sendTransaction({
|
|
7045
|
-
account: address,
|
|
7046
|
-
to: encodedTx.to,
|
|
7047
|
-
data: encodedTx.data,
|
|
7048
|
-
value: encodedTx.value
|
|
7049
|
-
});
|
|
7050
|
-
};
|
|
7051
|
-
const res = await cryptoPayment({
|
|
7052
|
-
hash: data.hash,
|
|
7053
|
-
coinSymbol: selectedPaymentMethod.method.symbol,
|
|
7054
|
-
publicKey: address,
|
|
7055
|
-
sendTransaction
|
|
7056
|
-
});
|
|
7057
|
-
if (["AUTHORIZED" /* AUTHORIZED */, "CAPTURED" /* CAPTURED */].includes(res.status)) {
|
|
7058
|
-
return Promise.resolve(res);
|
|
7059
|
-
}
|
|
7060
|
-
return Promise.reject(new PaymentError("Crypto payment failed", res.status));
|
|
7144
|
+
const res = await cryptoPayment({ hash: data.hash });
|
|
7145
|
+
if (["AUTHORIZED" /* AUTHORIZED */, "CAPTURED" /* CAPTURED */].includes(res.status)) {
|
|
7146
|
+
return Promise.resolve(res);
|
|
7061
7147
|
}
|
|
7062
|
-
return Promise.reject(new PaymentError("
|
|
7148
|
+
return Promise.reject(new PaymentError("Crypto payment failed", res.status));
|
|
7063
7149
|
} catch (_) {
|
|
7064
7150
|
return Promise.reject(new PaymentError("Payment failed", "FAILED" /* FAILED */));
|
|
7065
7151
|
}
|
|
7066
7152
|
},
|
|
7067
|
-
[
|
|
7153
|
+
[cryptoPayment]
|
|
7068
7154
|
);
|
|
7069
7155
|
useEffect19(() => {
|
|
7070
7156
|
register(handlePay);
|
|
@@ -7092,10 +7178,19 @@ var Crypto = () => {
|
|
|
7092
7178
|
// src/components/CryptoTab/Crypto/CryptoWrapper.tsx
|
|
7093
7179
|
import { jsx as jsx32 } from "react/jsx-runtime";
|
|
7094
7180
|
var queryClient = new QueryClient();
|
|
7095
|
-
var
|
|
7096
|
-
|
|
7097
|
-
|
|
7181
|
+
var connectors = connectorsForWallets(
|
|
7182
|
+
[
|
|
7183
|
+
{
|
|
7184
|
+
groupName: "Supported",
|
|
7185
|
+
wallets: [injectedWallet, walletConnectWallet]
|
|
7186
|
+
}
|
|
7187
|
+
],
|
|
7188
|
+
{ appName: "Spree Pay", projectId: "YOUR_PROJECT_ID" }
|
|
7189
|
+
);
|
|
7190
|
+
var config = createConfig({
|
|
7098
7191
|
chains: [base],
|
|
7192
|
+
connectors,
|
|
7193
|
+
transports: { [base.id]: http2() },
|
|
7099
7194
|
ssr: true
|
|
7100
7195
|
});
|
|
7101
7196
|
var CryptoWrapper = () => {
|
|
@@ -7174,7 +7269,7 @@ var Tabs = () => {
|
|
|
7174
7269
|
const { selectedPaymentMethod, setSelectedPaymentMethod } = useSpreePaymentMethod();
|
|
7175
7270
|
return /* @__PURE__ */ jsxs22("div", { className: "mb-4 rounded-2xl border border-black/25 bg-white", children: [
|
|
7176
7271
|
/* @__PURE__ */ jsxs22("div", { className: "flex w-full flex-col gap-4 border-b-1 border-black/7 px-7 py-6", children: [
|
|
7177
|
-
/* @__PURE__ */ jsx35("h2", { className: "text-primary text-2xl font-semibold", children: "Choose a
|
|
7272
|
+
/* @__PURE__ */ jsx35("h2", { className: "text-primary text-2xl font-semibold", children: "Choose a Payment Method" }),
|
|
7178
7273
|
/* @__PURE__ */ jsx35(TabButtons, { value: selectedPaymentMethod.type, onChange: setSelectedPaymentMethod })
|
|
7179
7274
|
] }),
|
|
7180
7275
|
selectedPaymentMethod.type === "CREDIT_CARD" /* CREDIT_CARD */ && /* @__PURE__ */ jsx35(CreditCardTab, {}),
|
|
@@ -7185,32 +7280,151 @@ var Tabs = () => {
|
|
|
7185
7280
|
// src/SpreePayContent.tsx
|
|
7186
7281
|
import { jsx as jsx36, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
7187
7282
|
var SpreePayContent = (props) => {
|
|
7188
|
-
const {
|
|
7189
|
-
return /* @__PURE__ */
|
|
7283
|
+
const { amount, onProcess } = props;
|
|
7284
|
+
return /* @__PURE__ */ jsxs23("div", { className: "w-full", children: [
|
|
7190
7285
|
/* @__PURE__ */ jsx36(Tabs, {}),
|
|
7191
7286
|
/* @__PURE__ */ jsx36(CheckoutButton, { onCheckout: onProcess, amount }),
|
|
7192
7287
|
/* @__PURE__ */ jsx36(SpreeLegal, {})
|
|
7193
|
-
] })
|
|
7288
|
+
] });
|
|
7194
7289
|
};
|
|
7195
7290
|
|
|
7291
|
+
// src/hooks/useKeycloakSSO.ts
|
|
7292
|
+
import { useCallback as useCallback10, useEffect as useEffect20, useRef as useRef14, useState as useState18 } from "react";
|
|
7293
|
+
import Keycloak from "keycloak-js";
|
|
7294
|
+
var refreshAheadSeconds = 60;
|
|
7295
|
+
function useKeycloakSSO(config2) {
|
|
7296
|
+
const { url, realm, clientId, ssoPageURI, enabled } = config2;
|
|
7297
|
+
const initRef = useRef14(false);
|
|
7298
|
+
const kcRef = useRef14(null);
|
|
7299
|
+
const refreshTimerRef = useRef14(null);
|
|
7300
|
+
const [error, setError] = useState18(null);
|
|
7301
|
+
const [isChecking, setIsChecking] = useState18(false);
|
|
7302
|
+
const [accessToken, setAccessToken] = useState18(null);
|
|
7303
|
+
const scheduleRefresh = useCallback10(() => {
|
|
7304
|
+
const kc = kcRef.current;
|
|
7305
|
+
if (!kc || !kc.tokenParsed || !kc.tokenParsed.exp) {
|
|
7306
|
+
return;
|
|
7307
|
+
}
|
|
7308
|
+
const expSeconds = kc.tokenParsed.exp;
|
|
7309
|
+
const nowSeconds = Math.floor(Date.now() / 1e3);
|
|
7310
|
+
const delaySeconds = Math.max(expSeconds - nowSeconds - refreshAheadSeconds, 5);
|
|
7311
|
+
const delayMs = delaySeconds * 1e3;
|
|
7312
|
+
if (refreshTimerRef.current) clearTimeout(refreshTimerRef.current);
|
|
7313
|
+
refreshTimerRef.current = setTimeout(() => {
|
|
7314
|
+
kc.updateToken(refreshAheadSeconds).then((refreshed) => {
|
|
7315
|
+
if (refreshed) {
|
|
7316
|
+
setAccessToken(kc.token ?? null);
|
|
7317
|
+
scheduleRefresh();
|
|
7318
|
+
}
|
|
7319
|
+
}).catch((_) => {
|
|
7320
|
+
kc.login().catch(console.error);
|
|
7321
|
+
});
|
|
7322
|
+
}, delayMs);
|
|
7323
|
+
}, []);
|
|
7324
|
+
useEffect20(() => {
|
|
7325
|
+
if (initRef.current || !enabled) return;
|
|
7326
|
+
initRef.current = true;
|
|
7327
|
+
setIsChecking(true);
|
|
7328
|
+
const kc = new Keycloak({ url, realm, clientId });
|
|
7329
|
+
kcRef.current = kc;
|
|
7330
|
+
kc.onTokenExpired = () => {
|
|
7331
|
+
kc.updateToken(refreshAheadSeconds).then((refreshed) => {
|
|
7332
|
+
if (refreshed) {
|
|
7333
|
+
setAccessToken(kc.token ?? null);
|
|
7334
|
+
scheduleRefresh();
|
|
7335
|
+
}
|
|
7336
|
+
}).catch((err) => {
|
|
7337
|
+
console.error("[Keycloak] onTokenExpired refresh failed", err);
|
|
7338
|
+
});
|
|
7339
|
+
};
|
|
7340
|
+
kc.init({
|
|
7341
|
+
onLoad: "check-sso",
|
|
7342
|
+
silentCheckSsoRedirectUri: `${window.location.origin}${ssoPageURI}`,
|
|
7343
|
+
silentCheckSsoFallback: true
|
|
7344
|
+
}).then((auth) => {
|
|
7345
|
+
console.log("[Keycloak] init success, authenticated=", auth);
|
|
7346
|
+
setAccessToken(kc.token ?? null);
|
|
7347
|
+
if (auth) scheduleRefresh();
|
|
7348
|
+
}).catch((err) => {
|
|
7349
|
+
setError(err);
|
|
7350
|
+
}).finally(() => setIsChecking(false));
|
|
7351
|
+
return () => {
|
|
7352
|
+
if (refreshTimerRef.current) clearTimeout(refreshTimerRef.current);
|
|
7353
|
+
};
|
|
7354
|
+
}, [ssoPageURI, scheduleRefresh, clientId, url, realm]);
|
|
7355
|
+
return { isChecking, accessToken, error };
|
|
7356
|
+
}
|
|
7357
|
+
|
|
7196
7358
|
// src/SpreePay.tsx
|
|
7197
|
-
import { jsx as jsx37 } from "react/jsx-runtime";
|
|
7359
|
+
import { jsx as jsx37, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
7198
7360
|
var envConfig = {
|
|
7199
|
-
dev: {
|
|
7200
|
-
|
|
7201
|
-
|
|
7361
|
+
dev: {
|
|
7362
|
+
bookit: {
|
|
7363
|
+
slapiUrl: "https://slapi.dev.superlogic.com",
|
|
7364
|
+
keyklockUrl: "https://auth.dev.join.bookit.com",
|
|
7365
|
+
keyklockClientId: "oneof-next"
|
|
7366
|
+
},
|
|
7367
|
+
moca: {
|
|
7368
|
+
slapiUrl: "https://slapi.dev.air.shop",
|
|
7369
|
+
keyklockUrl: "https://login.dev.air.shop",
|
|
7370
|
+
keyklockClientId: "oneof-next"
|
|
7371
|
+
}
|
|
7372
|
+
},
|
|
7373
|
+
stg: {
|
|
7374
|
+
bookit: {
|
|
7375
|
+
slapiUrl: "https://slapi.stg.superlogic.com",
|
|
7376
|
+
keyklockUrl: "https://auth.stg.join.bookit.com",
|
|
7377
|
+
keyklockClientId: "oneof-next"
|
|
7378
|
+
},
|
|
7379
|
+
moca: {
|
|
7380
|
+
slapiUrl: "https://slapi.stg.superlogic.com",
|
|
7381
|
+
keyklockUrl: "https://login.stg.air.shop",
|
|
7382
|
+
keyklockClientId: "oneof-next"
|
|
7383
|
+
}
|
|
7384
|
+
},
|
|
7385
|
+
prod: {
|
|
7386
|
+
bookit: {
|
|
7387
|
+
slapiUrl: "https://slapi.superlogic.com",
|
|
7388
|
+
keyklockUrl: "https://auth.join.bookit.com",
|
|
7389
|
+
keyklockClientId: "oneof-next"
|
|
7390
|
+
},
|
|
7391
|
+
moca: {
|
|
7392
|
+
slapiUrl: "https://slapi.superlogic.com",
|
|
7393
|
+
keyklockUrl: "https://login.air.shop",
|
|
7394
|
+
keyklockClientId: "oneof-next"
|
|
7395
|
+
}
|
|
7396
|
+
}
|
|
7202
7397
|
};
|
|
7203
|
-
var SpreePay = (
|
|
7398
|
+
var SpreePay = ({ className, ...rest }) => {
|
|
7204
7399
|
const { env } = useSpreePayEnv();
|
|
7205
|
-
const
|
|
7206
|
-
|
|
7207
|
-
|
|
7208
|
-
|
|
7209
|
-
|
|
7210
|
-
|
|
7211
|
-
|
|
7212
|
-
|
|
7213
|
-
|
|
7400
|
+
const environment = env?.environment || "dev";
|
|
7401
|
+
const tenantId = env?.tenantId || "bookit";
|
|
7402
|
+
const { isChecking, accessToken, error } = useKeycloakSSO({
|
|
7403
|
+
realm: env.tenantId,
|
|
7404
|
+
url: envConfig[environment][tenantId].keyklockUrl,
|
|
7405
|
+
clientId: envConfig[environment][tenantId].keyklockClientId,
|
|
7406
|
+
ssoPageURI: env.ssoPageURI,
|
|
7407
|
+
enabled: !env.accessToken
|
|
7408
|
+
});
|
|
7409
|
+
const slapiFetcher = useMemo7(() => {
|
|
7410
|
+
if (accessToken || env.accessToken) {
|
|
7411
|
+
return registerApi({
|
|
7412
|
+
accessToken: env.accessToken || accessToken,
|
|
7413
|
+
tenantId,
|
|
7414
|
+
baseUrl: envConfig[environment][tenantId].slapiUrl
|
|
7415
|
+
});
|
|
7416
|
+
}
|
|
7417
|
+
}, [env.accessToken, environment, tenantId, accessToken]);
|
|
7418
|
+
if (isChecking) {
|
|
7419
|
+
return /* @__PURE__ */ jsx37("div", { className: cn("sl-spreepay", className), children: /* @__PURE__ */ jsx37("p", { className: "w-full text-center text-sm", children: "Loading..." }) });
|
|
7420
|
+
}
|
|
7421
|
+
if (error) {
|
|
7422
|
+
return /* @__PURE__ */ jsx37("div", { className: cn("sl-spreepay", className), children: /* @__PURE__ */ jsxs24("p", { className: "w-full text-center text-sm", children: [
|
|
7423
|
+
"Error: ",
|
|
7424
|
+
error.message
|
|
7425
|
+
] }) });
|
|
7426
|
+
}
|
|
7427
|
+
return /* @__PURE__ */ jsx37("div", { className: cn("sl-spreepay", className), children: /* @__PURE__ */ jsx37(
|
|
7214
7428
|
SWRConfig,
|
|
7215
7429
|
{
|
|
7216
7430
|
value: {
|
|
@@ -7219,15 +7433,15 @@ var SpreePay = (props) => {
|
|
|
7219
7433
|
revalidateIfStale: false,
|
|
7220
7434
|
revalidateOnReconnect: false
|
|
7221
7435
|
},
|
|
7222
|
-
children: /* @__PURE__ */ jsx37(NiceModal6.Provider, { children: /* @__PURE__ */ jsx37(SpreePayContent, { ...
|
|
7436
|
+
children: /* @__PURE__ */ jsx37(NiceModal6.Provider, { children: /* @__PURE__ */ jsx37(SpreePayContent, { ...rest }) })
|
|
7223
7437
|
}
|
|
7224
|
-
);
|
|
7438
|
+
) });
|
|
7225
7439
|
};
|
|
7226
7440
|
|
|
7227
7441
|
// src/hooks/useCapture3DS.ts
|
|
7228
|
-
import { useEffect as
|
|
7442
|
+
import { useEffect as useEffect21 } from "react";
|
|
7229
7443
|
var useCapture3DS = (searchParams) => {
|
|
7230
|
-
|
|
7444
|
+
useEffect21(() => {
|
|
7231
7445
|
if (window?.parent && searchParams?.paymentIntent) {
|
|
7232
7446
|
window.parent.SP_EVENT_BUS?.emit("paymentIntent", { paymentIntent: searchParams.paymentIntent });
|
|
7233
7447
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@superlogic/spree-pay",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "Spree-pay React component and utilities",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
@@ -32,9 +32,10 @@
|
|
|
32
32
|
"@stripe/react-stripe-js": "^3.9.0",
|
|
33
33
|
"@stripe/stripe-js": "^7.8.0",
|
|
34
34
|
"@tanstack/react-query": "^5.85.5",
|
|
35
|
+
"keycloak-js": "^26.2.0",
|
|
35
36
|
"swr": "^2.3.6",
|
|
36
|
-
"viem": "^2.
|
|
37
|
-
"wagmi": "^2.16.
|
|
37
|
+
"viem": "^2.37.6",
|
|
38
|
+
"wagmi": "^2.16.9"
|
|
38
39
|
},
|
|
39
40
|
"devDependencies": {
|
|
40
41
|
"@repo/eslint-config": "^1.0.0",
|