@b3dotfun/sdk 0.0.1-alpha.2 → 0.0.1-alpha.21
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 +328 -230
- package/dist/cjs/anyspend/index.native.d.ts +13 -0
- package/dist/cjs/anyspend/index.native.js +35 -0
- package/dist/cjs/anyspend/react/components/AnySpend.d.ts +2 -1
- package/dist/cjs/anyspend/react/components/AnySpend.js +4 -4
- package/dist/cjs/anyspend/react/components/AnySpendBuySpin.d.ts +2 -1
- package/dist/cjs/anyspend/react/components/AnySpendBuySpin.js +123 -50
- package/dist/cjs/anyspend/react/components/common/OrderHistoryItem.js +5 -1
- package/dist/cjs/anyspend/react/components/common/TokenBalance.js +1 -1
- package/dist/cjs/anyspend/utils/chain.js +3 -0
- package/dist/cjs/global-account/react/components/B3DynamicModal.js +2 -2
- package/dist/cjs/global-account/react/components/{B3Provider.d.ts → B3Provider/B3Provider.d.ts} +3 -29
- package/dist/cjs/global-account/react/components/{B3Provider.js → B3Provider/B3Provider.js} +6 -34
- package/dist/cjs/global-account/react/components/{B3Provider.native.d.ts → B3Provider/B3Provider.native.d.ts} +2 -25
- package/dist/cjs/global-account/react/components/{B3Provider.native.js → B3Provider/B3Provider.native.js} +5 -28
- package/dist/cjs/global-account/react/components/B3Provider/types.d.ts +25 -0
- package/dist/cjs/global-account/react/components/B3Provider/types.js +20 -0
- package/dist/cjs/global-account/react/components/B3Provider/useB3.d.ts +5 -0
- package/dist/cjs/global-account/react/components/B3Provider/useB3.js +17 -0
- package/dist/cjs/global-account/react/components/StyleRoot.js +2 -2
- package/dist/cjs/global-account/react/components/index.d.ts +8 -6
- package/dist/cjs/global-account/react/components/index.js +18 -16
- package/dist/cjs/global-account/react/hooks/index.d.ts +1 -1
- package/dist/cjs/global-account/react/hooks/index.js +2 -1
- package/dist/cjs/global-account/react/hooks/useBestTransactionPath.js +3 -3
- package/dist/cjs/global-account/react/hooks/useTokenBalance.js +1 -1
- package/dist/cjs/global-account/react/index.native.d.ts +7 -0
- package/dist/cjs/global-account/react/index.native.js +21 -0
- package/dist/cjs/global-account/react/stores/useModalStore.d.ts +2 -0
- package/dist/cjs/global-account/types/chain-networks.d.ts +34 -34
- package/dist/cjs/global-account/types/feature-flags.d.ts +5 -5
- package/dist/cjs/shared/constants/chains/b3Chain.d.ts +1 -1
- package/dist/cjs/shared/constants/chains/supported.d.ts +8 -7
- package/dist/cjs/shared/constants/chains/supported.js +8 -1
- package/dist/cjs/shared/utils/chains.js +4 -0
- package/dist/cjs/shared/utils/number.js +1 -1
- package/dist/esm/anyspend/index.native.d.ts +13 -0
- package/dist/esm/anyspend/index.native.js +19 -0
- package/dist/esm/anyspend/react/components/AnySpend.d.ts +2 -1
- package/dist/esm/anyspend/react/components/AnySpend.js +4 -4
- package/dist/esm/anyspend/react/components/AnySpendBuySpin.d.ts +2 -1
- package/dist/esm/anyspend/react/components/AnySpendBuySpin.js +123 -50
- package/dist/esm/anyspend/react/components/common/OrderHistoryItem.js +5 -1
- package/dist/esm/anyspend/react/components/common/TokenBalance.js +1 -1
- package/dist/esm/anyspend/utils/chain.js +3 -0
- package/dist/esm/global-account/react/components/B3DynamicModal.js +1 -1
- package/dist/esm/global-account/react/components/{B3Provider.d.ts → B3Provider/B3Provider.d.ts} +3 -29
- package/dist/esm/global-account/react/components/{B3Provider.js → B3Provider/B3Provider.js} +5 -32
- package/dist/esm/global-account/react/components/{B3Provider.native.d.ts → B3Provider/B3Provider.native.d.ts} +2 -25
- package/dist/esm/global-account/react/components/{B3Provider.native.js → B3Provider/B3Provider.native.js} +5 -26
- package/dist/esm/global-account/react/components/B3Provider/types.d.ts +25 -0
- package/dist/esm/global-account/react/components/B3Provider/types.js +17 -0
- package/dist/esm/global-account/react/components/B3Provider/useB3.d.ts +5 -0
- package/dist/esm/global-account/react/components/B3Provider/useB3.js +14 -0
- package/dist/esm/global-account/react/components/StyleRoot.js +1 -1
- package/dist/esm/global-account/react/components/index.d.ts +8 -6
- package/dist/esm/global-account/react/components/index.js +7 -5
- package/dist/esm/global-account/react/hooks/index.d.ts +1 -1
- package/dist/esm/global-account/react/hooks/index.js +1 -1
- package/dist/esm/global-account/react/hooks/useBestTransactionPath.js +3 -3
- package/dist/esm/global-account/react/hooks/useTokenBalance.js +1 -1
- package/dist/esm/global-account/react/index.native.d.ts +7 -0
- package/dist/esm/global-account/react/index.native.js +11 -0
- package/dist/esm/global-account/react/stores/useModalStore.d.ts +2 -0
- package/dist/esm/global-account/types/chain-networks.d.ts +34 -34
- package/dist/esm/global-account/types/feature-flags.d.ts +5 -5
- package/dist/esm/shared/constants/chains/b3Chain.d.ts +1 -1
- package/dist/esm/shared/constants/chains/supported.d.ts +8 -7
- package/dist/esm/shared/constants/chains/supported.js +7 -0
- package/dist/esm/shared/utils/chains.js +4 -0
- package/dist/esm/shared/utils/number.js +1 -1
- package/dist/styles/index.css +1 -1
- package/dist/types/anyspend/index.native.d.ts +13 -0
- package/dist/types/anyspend/react/components/AnySpend.d.ts +2 -1
- package/dist/types/anyspend/react/components/AnySpendBuySpin.d.ts +2 -1
- package/dist/types/global-account/react/components/{B3Provider.d.ts → B3Provider/B3Provider.d.ts} +2 -28
- package/dist/types/global-account/react/components/{B3Provider.native.d.ts → B3Provider/B3Provider.native.d.ts} +1 -24
- package/dist/types/global-account/react/components/B3Provider/types.d.ts +25 -0
- package/dist/types/global-account/react/components/B3Provider/useB3.d.ts +5 -0
- package/dist/types/global-account/react/components/index.d.ts +8 -6
- package/dist/types/global-account/react/hooks/index.d.ts +1 -1
- package/dist/types/global-account/react/index.native.d.ts +7 -0
- package/dist/types/global-account/react/stores/useModalStore.d.ts +2 -0
- package/dist/types/global-account/types/chain-networks.d.ts +34 -34
- package/dist/types/global-account/types/feature-flags.d.ts +5 -5
- package/dist/types/shared/constants/chains/b3Chain.d.ts +1 -1
- package/dist/types/shared/constants/chains/supported.d.ts +8 -7
- package/package.json +26 -24
- package/src/anyspend/index.native.ts +24 -0
- package/src/anyspend/react/components/AnySpend.tsx +6 -5
- package/src/anyspend/react/components/AnySpendBuySpin.tsx +232 -179
- package/src/anyspend/react/components/common/OrderHistoryItem.tsx +5 -1
- package/src/anyspend/react/components/common/TokenBalance.tsx +1 -1
- package/src/anyspend/utils/chain.ts +3 -0
- package/src/global-account/react/components/B3DynamicModal.tsx +1 -1
- package/src/global-account/react/components/{B3Provider.native.tsx → B3Provider/B3Provider.native.tsx} +4 -45
- package/src/global-account/react/components/{B3Provider.tsx → B3Provider/B3Provider.tsx} +4 -53
- package/src/global-account/react/components/B3Provider/types.ts +40 -0
- package/src/global-account/react/components/B3Provider/useB3.ts +17 -0
- package/src/global-account/react/components/StyleRoot.tsx +1 -1
- package/src/global-account/react/components/index.ts +8 -6
- package/src/global-account/react/hooks/index.ts +1 -1
- package/src/global-account/react/hooks/useBestTransactionPath.tsx +3 -3
- package/src/global-account/react/hooks/useTokenBalance.tsx +1 -1
- package/src/global-account/react/index.native.ts +14 -0
- package/src/global-account/react/stores/useModalStore.ts +2 -0
- package/src/shared/constants/chains/supported.ts +12 -4
- package/src/shared/utils/chains.ts +4 -1
- package/src/shared/utils/number.ts +1 -1
- package/dist/cjs/styles/index.d.ts +0 -20
- package/dist/cjs/styles/index.js +0 -22
- package/dist/esm/styles/index.d.ts +0 -20
- package/dist/esm/styles/index.js +0 -20
- package/dist/types/styles/index.d.ts +0 -20
- package/src/styles/index.ts +0 -24
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Export all hooks
|
|
2
|
+
export * from "./react/hooks";
|
|
3
|
+
// Providers
|
|
4
|
+
export * from "./react/providers/AnyspendProvider";
|
|
5
|
+
// Types
|
|
6
|
+
export * from "./types";
|
|
7
|
+
// Utils
|
|
8
|
+
export * from "./utils/address";
|
|
9
|
+
export * from "./utils/chain";
|
|
10
|
+
export * from "./utils/format";
|
|
11
|
+
export * from "./utils/json";
|
|
12
|
+
export * from "./utils/number";
|
|
13
|
+
export * from "./utils/string";
|
|
14
|
+
export * from "./utils/token";
|
|
15
|
+
// Constants
|
|
16
|
+
export * from "./constants";
|
|
17
|
+
// Abis
|
|
18
|
+
export * from "./abis/abi-usdc-base";
|
|
19
|
+
export * from "./abis/erc20-staking";
|
|
@@ -11,7 +11,7 @@ export declare enum PanelView {
|
|
|
11
11
|
LOADING = 3,
|
|
12
12
|
FIAT_PAYMENT = 4
|
|
13
13
|
}
|
|
14
|
-
export declare function AnySpend({ destinationTokenAddress, destinationTokenChainId, isMainnet, mode, defaultActiveTab, loadOrder, hideTransactionHistoryButton }: {
|
|
14
|
+
export declare function AnySpend({ destinationTokenAddress, destinationTokenChainId, isMainnet, mode, defaultActiveTab, loadOrder, hideTransactionHistoryButton, recipientAddress: recipientAddressFromProps }: {
|
|
15
15
|
destinationTokenAddress?: string;
|
|
16
16
|
destinationTokenChainId?: number;
|
|
17
17
|
isMainnet?: boolean;
|
|
@@ -19,4 +19,5 @@ export declare function AnySpend({ destinationTokenAddress, destinationTokenChai
|
|
|
19
19
|
defaultActiveTab?: "crypto" | "fiat";
|
|
20
20
|
loadOrder?: string;
|
|
21
21
|
hideTransactionHistoryButton?: boolean;
|
|
22
|
+
recipientAddress?: string;
|
|
22
23
|
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { getDefaultToken, OrderType, TradeType, USDC_BASE, useAnyspendCreateOrder, useAnyspendOrderAndTransactions, useAnyspendQuote } from "../../../anyspend";
|
|
4
4
|
import { Button, ShinyButton, StyleRoot, TransitionPanel, useAccountWallet, useOnchainName, useRouter, useSearchParamsSSR, useTokenData, useTokenFromUrl } from "../../../global-account/react";
|
|
5
|
-
import { shortenAddress } from "../../../shared/utils/formatAddress";
|
|
6
5
|
import { cn } from "../../../shared/utils/cn";
|
|
6
|
+
import { shortenAddress } from "../../../shared/utils/formatAddress";
|
|
7
7
|
import { formatDisplayNumber, formatTokenAmount } from "../../../shared/utils/number";
|
|
8
8
|
import { motion } from "framer-motion";
|
|
9
9
|
import invariant from "invariant";
|
|
@@ -29,7 +29,7 @@ export var PanelView;
|
|
|
29
29
|
PanelView[PanelView["FIAT_PAYMENT"] = 4] = "FIAT_PAYMENT";
|
|
30
30
|
})(PanelView || (PanelView = {}));
|
|
31
31
|
const ANYSPEND_RECIPIENTS_KEY = "anyspend_recipients";
|
|
32
|
-
export function AnySpend({ destinationTokenAddress, destinationTokenChainId, isMainnet = true, mode = "modal", defaultActiveTab = "crypto", loadOrder, hideTransactionHistoryButton }) {
|
|
32
|
+
export function AnySpend({ destinationTokenAddress, destinationTokenChainId, isMainnet = true, mode = "modal", defaultActiveTab = "crypto", loadOrder, hideTransactionHistoryButton, recipientAddress: recipientAddressFromProps }) {
|
|
33
33
|
const searchParams = useSearchParamsSSR();
|
|
34
34
|
const router = useRouter();
|
|
35
35
|
// Determine if we're in "buy mode" based on whether destination token props are provided
|
|
@@ -272,8 +272,8 @@ export function AnySpend({ destinationTokenAddress, destinationTokenChainId, isM
|
|
|
272
272
|
const { address: globalAddress, wallet: globalWallet } = useAccountWallet();
|
|
273
273
|
// Set default recipient address when wallet changes
|
|
274
274
|
useEffect(() => {
|
|
275
|
-
setRecipientAddress(globalAddress);
|
|
276
|
-
}, [globalAddress]);
|
|
275
|
+
setRecipientAddress(recipientAddressFromProps || globalAddress);
|
|
276
|
+
}, [recipientAddressFromProps, globalAddress]);
|
|
277
277
|
// Get anyspend price
|
|
278
278
|
const activeInputAmountInWei = isSrcInputDirty
|
|
279
279
|
? parseUnits(srcAmount.replaceAll(",", ""), selectedSrcToken.decimals).toString()
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
export declare function AnySpendBuySpin({ isMainnet, loadOrder, mode, spinwheelContractAddress, chainId, recipientAddress, onSuccess }: {
|
|
1
|
+
export declare function AnySpendBuySpin({ isMainnet, loadOrder, mode, spinwheelContractAddress, chainId, recipientAddress, prefillQuantity, onSuccess }: {
|
|
2
2
|
isMainnet?: boolean;
|
|
3
3
|
loadOrder?: string;
|
|
4
4
|
mode?: "modal" | "page";
|
|
5
5
|
spinwheelContractAddress: string;
|
|
6
6
|
chainId: number;
|
|
7
7
|
recipientAddress: string;
|
|
8
|
+
prefillQuantity?: string;
|
|
8
9
|
onSuccess?: (txHash?: string) => void;
|
|
9
10
|
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { B3_TOKEN, OrderType } from "../../../anyspend";
|
|
3
|
+
import { baseMainnet } from "../../../shared/constants/chains/supported";
|
|
3
4
|
import { EthIcon } from "./icons/EthIcon";
|
|
4
5
|
import { SolIcon } from "./icons/SolIcon";
|
|
5
6
|
import { UsdcIcon } from "./icons/USDCIcon";
|
|
@@ -11,7 +12,6 @@ import { ArrowRight, Loader2 } from "lucide-react";
|
|
|
11
12
|
import { useCallback, useEffect, useState } from "react";
|
|
12
13
|
import { toast } from "sonner";
|
|
13
14
|
import { createPublicClient, encodeFunctionData, erc20Abi, formatUnits, http } from "viem";
|
|
14
|
-
import { base } from "viem/chains";
|
|
15
15
|
import { useAccount, useWaitForTransactionReceipt, useWriteContract } from "wagmi";
|
|
16
16
|
import { AnySpendCustom } from "./AnySpendCustom";
|
|
17
17
|
const SPIN_WHEEL_ABI = [
|
|
@@ -43,8 +43,37 @@ const SPIN_WHEEL_ABI = [
|
|
|
43
43
|
outputs: [],
|
|
44
44
|
stateMutability: "payable",
|
|
45
45
|
type: "function"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
inputs: [],
|
|
49
|
+
name: "getWheelInfo",
|
|
50
|
+
outputs: [
|
|
51
|
+
{ internalType: "address", name: "creator_", type: "address" },
|
|
52
|
+
{ internalType: "uint256", name: "startTime_", type: "uint256" },
|
|
53
|
+
{ internalType: "uint256", name: "endTime_", type: "uint256" },
|
|
54
|
+
{ internalType: "uint256", name: "totalPrizesAvailable_", type: "uint256" },
|
|
55
|
+
{ internalType: "uint256", name: "prizesRequestedCount_", type: "uint256" },
|
|
56
|
+
{ internalType: "enum SpinWheelV2.WheelState", name: "state_", type: "uint8" }
|
|
57
|
+
],
|
|
58
|
+
stateMutability: "view",
|
|
59
|
+
type: "function"
|
|
46
60
|
}
|
|
47
61
|
];
|
|
62
|
+
function getWheelStatus(wheelInfo) {
|
|
63
|
+
const now = BigInt(Math.floor(Date.now() / 1000));
|
|
64
|
+
console.log("@@anyspend-buy-spin:now:", now);
|
|
65
|
+
console.log("@@anyspend-buy-spin:wheelInfo:", wheelInfo);
|
|
66
|
+
if (now < wheelInfo.startTime_) {
|
|
67
|
+
return "not_started";
|
|
68
|
+
}
|
|
69
|
+
if (now > wheelInfo.endTime_) {
|
|
70
|
+
return "ended";
|
|
71
|
+
}
|
|
72
|
+
if (wheelInfo.totalPrizesAvailable_ <= wheelInfo.prizesRequestedCount_) {
|
|
73
|
+
return "sold_out";
|
|
74
|
+
}
|
|
75
|
+
return "active";
|
|
76
|
+
}
|
|
48
77
|
function generateEncodedDataForBuyEntriesAndSpin(user, quantity) {
|
|
49
78
|
invariant(BigInt(quantity) > 0, "Quantity must be greater than zero");
|
|
50
79
|
console.log("@@anyspend-buy-spin:encoded-data:", { user, quantity });
|
|
@@ -56,16 +85,17 @@ function generateEncodedDataForBuyEntriesAndSpin(user, quantity) {
|
|
|
56
85
|
return encodedData;
|
|
57
86
|
}
|
|
58
87
|
const basePublicClient = createPublicClient({
|
|
59
|
-
chain:
|
|
88
|
+
chain: baseMainnet,
|
|
60
89
|
transport: http()
|
|
61
90
|
});
|
|
62
|
-
export function AnySpendBuySpin({ isMainnet = true, loadOrder, mode = "modal", spinwheelContractAddress, chainId, recipientAddress, onSuccess }) {
|
|
91
|
+
export function AnySpendBuySpin({ isMainnet = true, loadOrder, mode = "modal", spinwheelContractAddress, chainId, recipientAddress, prefillQuantity, onSuccess }) {
|
|
63
92
|
const hasMounted = useHasMounted();
|
|
64
93
|
const { setB3ModalOpen } = useModalStore();
|
|
65
94
|
// Payment config state
|
|
66
95
|
const [paymentConfig, setPaymentConfig] = useState(null);
|
|
67
96
|
const [isLoadingConfig, setIsLoadingConfig] = useState(true);
|
|
68
97
|
const [configError, setConfigError] = useState("");
|
|
98
|
+
const [wheelInfo, setWheelInfo] = useState(null);
|
|
69
99
|
// Fetch B3 token balance
|
|
70
100
|
const { formattedBalance: b3Balance, isLoading: isBalanceLoading, rawBalance: b3RawBalance } = useTokenBalance({
|
|
71
101
|
token: B3_TOKEN
|
|
@@ -77,22 +107,29 @@ export function AnySpendBuySpin({ isMainnet = true, loadOrder, mode = "modal", s
|
|
|
77
107
|
// State for direct buying flow (when user has B3 tokens)
|
|
78
108
|
const [isBuying, setIsBuying] = useState(false);
|
|
79
109
|
const [buyingTxHash, setBuyingTxHash] = useState("");
|
|
80
|
-
const
|
|
81
|
-
// Wait for transaction confirmation
|
|
82
|
-
const { isLoading: isTxPending, isSuccess: isTxSuccess } = useWaitForTransactionReceipt({
|
|
110
|
+
const { isLoading: isTxPending, isSuccess: isTxSuccess, isError: isTxError, error: txError } = useWaitForTransactionReceipt({
|
|
83
111
|
hash: buyingTxHash,
|
|
84
112
|
query: {
|
|
85
113
|
structuralSharing: false
|
|
86
114
|
}
|
|
87
115
|
});
|
|
88
|
-
//
|
|
116
|
+
// Handle transaction status
|
|
89
117
|
useEffect(() => {
|
|
90
|
-
if (
|
|
91
|
-
|
|
92
|
-
|
|
118
|
+
if (!buyingTxHash)
|
|
119
|
+
return;
|
|
120
|
+
if (isTxSuccess) {
|
|
121
|
+
setB3ModalOpen(false);
|
|
122
|
+
onSuccess?.(buyingTxHash);
|
|
123
|
+
toast.success("Spin purchase transaction confirmed!");
|
|
124
|
+
setIsBuying(false);
|
|
125
|
+
}
|
|
126
|
+
else if (isTxError) {
|
|
127
|
+
console.error("@@anyspend-buy-spin:tx-error:", txError);
|
|
128
|
+
toast.error("Transaction failed. Please try again.");
|
|
129
|
+
setB3ModalOpen(false);
|
|
93
130
|
setIsBuying(false);
|
|
94
131
|
}
|
|
95
|
-
}, [isTxSuccess, buyingTxHash]);
|
|
132
|
+
}, [isTxSuccess, isTxError, buyingTxHash, onSuccess, setB3ModalOpen, txError]);
|
|
96
133
|
// Spin quantity state
|
|
97
134
|
const [userSpinQuantity, setUserSpinQuantity] = useState("");
|
|
98
135
|
const [showAmountPrompt, setShowAmountPrompt] = useState(true);
|
|
@@ -100,9 +137,17 @@ export function AnySpendBuySpin({ isMainnet = true, loadOrder, mode = "modal", s
|
|
|
100
137
|
const [validationError, setValidationError] = useState("");
|
|
101
138
|
const [displayQuantity, setDisplayQuantity] = useState("");
|
|
102
139
|
const [debouncedQuantity, setDebouncedQuantity] = useState("");
|
|
140
|
+
const [debouncedUserSpinQuantity, setDebouncedUserSpinQuantity] = useState("");
|
|
141
|
+
useEffect(() => {
|
|
142
|
+
if (prefillQuantity && wheelInfo) {
|
|
143
|
+
const remainingSpins = wheelInfo.totalPrizesAvailable_ - wheelInfo.prizesRequestedCount_;
|
|
144
|
+
const adjustedQuantity = BigInt(prefillQuantity) > remainingSpins ? remainingSpins.toString() : prefillQuantity;
|
|
145
|
+
validateAndSetQuantity(adjustedQuantity);
|
|
146
|
+
}
|
|
147
|
+
}, [prefillQuantity, wheelInfo]);
|
|
103
148
|
// Calculate total cost
|
|
104
149
|
const totalCost = paymentConfig && userSpinQuantity ? paymentConfig.pricePerEntry * BigInt(userSpinQuantity) : BigInt(0);
|
|
105
|
-
// Fetch payment configuration
|
|
150
|
+
// Fetch payment configuration and wheel info
|
|
106
151
|
const fetchPaymentConfig = useCallback(async () => {
|
|
107
152
|
if (!basePublicClient || !spinwheelContractAddress)
|
|
108
153
|
return;
|
|
@@ -110,7 +155,7 @@ export function AnySpendBuySpin({ isMainnet = true, loadOrder, mode = "modal", s
|
|
|
110
155
|
setIsLoadingConfig(true);
|
|
111
156
|
setConfigError("");
|
|
112
157
|
console.log("@@anyspend-buy-spin:fetch-config:", { spinwheelContractAddress, chainId });
|
|
113
|
-
const [config, entryModuleAddress] = await Promise.all([
|
|
158
|
+
const [config, entryModuleAddress, wheelInfo] = await Promise.all([
|
|
114
159
|
basePublicClient.readContract({
|
|
115
160
|
address: spinwheelContractAddress,
|
|
116
161
|
abi: SPIN_WHEEL_ABI,
|
|
@@ -120,6 +165,11 @@ export function AnySpendBuySpin({ isMainnet = true, loadOrder, mode = "modal", s
|
|
|
120
165
|
address: spinwheelContractAddress,
|
|
121
166
|
abi: SPIN_WHEEL_ABI,
|
|
122
167
|
functionName: "entryModule"
|
|
168
|
+
}),
|
|
169
|
+
basePublicClient.readContract({
|
|
170
|
+
address: spinwheelContractAddress,
|
|
171
|
+
abi: SPIN_WHEEL_ABI,
|
|
172
|
+
functionName: "getWheelInfo"
|
|
123
173
|
})
|
|
124
174
|
]);
|
|
125
175
|
const paymentConfig = {
|
|
@@ -128,13 +178,16 @@ export function AnySpendBuySpin({ isMainnet = true, loadOrder, mode = "modal", s
|
|
|
128
178
|
paymentRecipient: config[3],
|
|
129
179
|
entryModule: entryModuleAddress
|
|
130
180
|
};
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
181
|
+
const wheelInfoData = {
|
|
182
|
+
creator_: wheelInfo[0],
|
|
183
|
+
startTime_: wheelInfo[1],
|
|
184
|
+
endTime_: wheelInfo[2],
|
|
185
|
+
totalPrizesAvailable_: wheelInfo[3],
|
|
186
|
+
prizesRequestedCount_: wheelInfo[4],
|
|
187
|
+
state_: wheelInfo[5]
|
|
188
|
+
};
|
|
137
189
|
setPaymentConfig(paymentConfig);
|
|
190
|
+
setWheelInfo(wheelInfoData);
|
|
138
191
|
}
|
|
139
192
|
catch (error) {
|
|
140
193
|
console.error("@@anyspend-buy-spin:config-error:", error);
|
|
@@ -153,6 +206,7 @@ export function AnySpendBuySpin({ isMainnet = true, loadOrder, mode = "modal", s
|
|
|
153
206
|
useEffect(() => {
|
|
154
207
|
const timer = setTimeout(() => {
|
|
155
208
|
setDebouncedQuantity(displayQuantity);
|
|
209
|
+
setDebouncedUserSpinQuantity(userSpinQuantity);
|
|
156
210
|
}, 500);
|
|
157
211
|
return () => clearTimeout(timer);
|
|
158
212
|
}, [displayQuantity, userSpinQuantity]);
|
|
@@ -184,6 +238,13 @@ export function AnySpendBuySpin({ isMainnet = true, loadOrder, mode = "modal", s
|
|
|
184
238
|
setValidationError(`Maximum ${paymentConfig.maxEntriesPerUser.toString()} spins allowed`);
|
|
185
239
|
return;
|
|
186
240
|
}
|
|
241
|
+
// Check if quantity exceeds remaining entries
|
|
242
|
+
if (wheelInfo && BigInt(numValue) > wheelInfo.totalPrizesAvailable_ - wheelInfo.prizesRequestedCount_) {
|
|
243
|
+
setIsQuantityValid(false);
|
|
244
|
+
setUserSpinQuantity("");
|
|
245
|
+
setValidationError(`Only ${(wheelInfo.totalPrizesAvailable_ - wheelInfo.prizesRequestedCount_).toString()} spins remaining`);
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
187
248
|
setUserSpinQuantity(value);
|
|
188
249
|
setIsQuantityValid(true);
|
|
189
250
|
setValidationError("");
|
|
@@ -233,7 +294,7 @@ export function AnySpendBuySpin({ isMainnet = true, loadOrder, mode = "modal", s
|
|
|
233
294
|
catch (error) {
|
|
234
295
|
console.error("@@anyspend-buy-spin:error:", error);
|
|
235
296
|
toast.error("Spin purchase failed. Please try again.");
|
|
236
|
-
|
|
297
|
+
setB3ModalOpen(false);
|
|
237
298
|
}
|
|
238
299
|
finally {
|
|
239
300
|
setIsBuying(false);
|
|
@@ -271,46 +332,58 @@ export function AnySpendBuySpin({ isMainnet = true, loadOrder, mode = "modal", s
|
|
|
271
332
|
// Render quantity input prompt
|
|
272
333
|
if (showAmountPrompt) {
|
|
273
334
|
const pricePerEntry = formatUnits(paymentConfig.pricePerEntry, 18);
|
|
335
|
+
const remainingEntries = wheelInfo ? wheelInfo.totalPrizesAvailable_ - wheelInfo.prizesRequestedCount_ : 0n;
|
|
336
|
+
const wheelStatus = wheelInfo ? getWheelStatus(wheelInfo) : null;
|
|
337
|
+
const isSoldOut = wheelStatus === "sold_out";
|
|
338
|
+
const isActive = wheelStatus === "active";
|
|
339
|
+
const getStatusMessage = () => {
|
|
340
|
+
if (!wheelInfo)
|
|
341
|
+
return null;
|
|
342
|
+
const formatDate = (timestamp) => {
|
|
343
|
+
return new Date(Number(timestamp) * 1000).toLocaleString();
|
|
344
|
+
};
|
|
345
|
+
switch (wheelStatus) {
|
|
346
|
+
case "not_started":
|
|
347
|
+
return {
|
|
348
|
+
title: "Spin Wheel Not Started",
|
|
349
|
+
message: `Starts at ${formatDate(wheelInfo.startTime_)}`
|
|
350
|
+
};
|
|
351
|
+
case "ended":
|
|
352
|
+
return {
|
|
353
|
+
title: "Spin Wheel Ended",
|
|
354
|
+
message: `Ended at ${formatDate(wheelInfo.endTime_)}`
|
|
355
|
+
};
|
|
356
|
+
case "sold_out":
|
|
357
|
+
return {
|
|
358
|
+
title: "All Spins Have Been Claimed",
|
|
359
|
+
message: "Stay tuned for the next spin wheel event!"
|
|
360
|
+
};
|
|
361
|
+
default:
|
|
362
|
+
return null;
|
|
363
|
+
}
|
|
364
|
+
};
|
|
365
|
+
const statusInfo = getStatusMessage();
|
|
274
366
|
return (_jsx(StyleRoot, { children: _jsxs("div", { className: "bg-b3-react-background flex w-full flex-col items-center", children: [_jsxs("div", { className: "w-full px-4 pb-2 pt-4", children: [_jsx(motion.div, { initial: false, animate: {
|
|
275
367
|
opacity: hasMounted ? 1 : 0,
|
|
276
368
|
y: hasMounted ? 0 : 20,
|
|
277
369
|
filter: hasMounted ? "blur(0px)" : "blur(10px)"
|
|
278
|
-
}, transition: { duration: 0.3, delay: 0, ease: "easeInOut" }, className: "mb-4
|
|
279
|
-
opacity: hasMounted ? 1 : 0,
|
|
280
|
-
y: hasMounted ? 0 : 20,
|
|
281
|
-
filter: hasMounted ? "blur(0px)" : "blur(10px)"
|
|
282
|
-
}, transition: { duration: 0.3, delay: 0.1, ease: "easeInOut" }, className: "text-center", children: [_jsx("h2", { className: "font-sf-rounded text-as-primary mb-2 text-2xl font-bold", children: (() => {
|
|
283
|
-
const hasEnoughBalance = b3RawBalance && totalCost <= b3RawBalance;
|
|
284
|
-
return hasEnoughBalance || !debouncedQuantity ? "Buy Spins" : `Swap & Buy Spins`;
|
|
285
|
-
})() }), _jsx("div", { className: "bg-as-on-surface-2/50 inline-flex items-center gap-2 rounded-full border border-white/10 px-3 py-1 backdrop-blur-sm", children: _jsxs("p", { className: "text-as-primary/80 text-sm", children: [pricePerEntry, " $B3 per spin"] }) })] })] }), _jsxs(motion.div, { initial: false, animate: {
|
|
286
|
-
opacity: hasMounted ? 1 : 0,
|
|
287
|
-
y: hasMounted ? 0 : 20,
|
|
288
|
-
filter: hasMounted ? "blur(0px)" : "blur(10px)"
|
|
289
|
-
}, transition: { duration: 0.3, delay: 0.2, ease: "easeInOut" }, className: "bg-b3-react-background w-full p-6", children: [_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("p", { className: "text-as-primary/70 text-sm font-medium", children: "Number of spins" }), _jsxs("span", { className: "text-as-primary/50 flex items-center gap-1 text-sm", children: ["Available: ", isBalanceLoading ? _jsx(Loader2, { className: "h-3 w-3 animate-spin" }) : `${b3Balance} B3`] })] }), _jsxs("div", { className: "relative", children: [_jsx(Input, { onFocus: onFocusQuantityInput, type: "text", placeholder: "1", value: displayQuantity, onChange: e => validateAndSetQuantity(e.target.value), className: `h-14 px-4 pr-20 text-lg ${!isQuantityValid && displayQuantity ? "border-as-red" : "border-b3-react-border"}` }), _jsx("div", { className: "font-pack absolute right-4 top-1/2 -translate-y-1/2 text-lg font-medium text-blue-500/70", children: displayQuantity === "1" ? "Spin" : "Spins" })] }), !isQuantityValid && displayQuantity && _jsx("p", { className: "text-as-red text-sm", children: validationError }), _jsx("div", { className: "bg-as-on-surface-2/30 rounded-lg border border-white/10 p-4 backdrop-blur-sm", children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-as-primary/70 text-sm font-medium", children: "Total Cost:" }), _jsx("div", { className: "flex items-center gap-2", children: _jsxs("span", { className: "text-as-primary text-lg font-bold", children: [displayQuantity && isQuantityValid ? formatUnits(totalCost, 18) : "0", " B3"] }) })] }) })] }), _jsx("div", { className: "mt-4", children: (() => {
|
|
290
|
-
const hasEnoughBalance = b3RawBalance && totalCost <= b3RawBalance;
|
|
291
|
-
if (!hasEnoughBalance && debouncedQuantity) {
|
|
292
|
-
return (_jsxs("div", { className: "bg-as-brand/10 flex flex-col items-center gap-2 rounded-lg p-4 pb-5", children: [_jsxs("div", { className: "flex items-center justify-center gap-2", children: [_jsx("span", { className: "text-as-primary text-sm font-semibold", children: "Swap & buy from any token" }), _jsxs(TextLoop, { children: [_jsx(EthIcon, { className: "h-8 w-8" }), _jsx(SolIcon, { className: "h-8 w-8" }), _jsx(UsdcIcon, { className: "h-8 w-8" })] }), _jsx(ArrowRight, { className: "text-as-primary h-4 w-4" }), _jsx("img", { src: "https://cdn.b3.fun/b3-coin-3d.png", className: "h-7 w-7", alt: "B3 Token" })] }), _jsx("p", { className: "text-as-primary/50 text-sm font-medium", children: "No problem, we'll help you swap to B3 for your spins!" })] }));
|
|
293
|
-
}
|
|
294
|
-
})() }), _jsx(Button, { onClick: confirmQuantity, disabled: !isQuantityValid || !displayQuantity || isBuying || isTxPending, className: "bg-as-brand hover:bg-as-brand/90 text-as-primary mt-4 h-14 w-full rounded-xl text-lg font-medium", children: isBuying ? "Buying..." : isTxPending ? "Confirming..." : "Continue" })] })] }) }));
|
|
295
|
-
}
|
|
296
|
-
// Success Modal for Direct Buying
|
|
297
|
-
if (showSuccessModal) {
|
|
298
|
-
return (_jsx(StyleRoot, { children: _jsxs("div", { className: "bg-b3-react-background flex w-full flex-col items-center", children: [_jsxs("div", { className: "w-full p-4", children: [_jsxs(motion.div, { initial: false, animate: {
|
|
299
|
-
opacity: hasMounted ? 1 : 0,
|
|
300
|
-
y: hasMounted ? 0 : 20,
|
|
301
|
-
filter: hasMounted ? "blur(0px)" : "blur(10px)"
|
|
302
|
-
}, transition: { duration: 0.3, delay: 0, ease: "easeInOut" }, className: "relative mx-auto mb-4 size-[120px]", children: [_jsx("div", { className: "absolute inset-0 scale-95 rounded-[50%] bg-gradient-to-br from-green-500/30 to-blue-500/30 blur-xl" }), _jsxs(GlareCardRounded, { className: "overflow-hidden rounded-full border-none bg-gradient-to-br from-green-500/10 to-blue-500/10 backdrop-blur-sm", children: [_jsx("img", { alt: "B3 Token", loading: "lazy", width: "120", height: "120", decoding: "async", "data-nimg": "1", className: "size-full shrink-0 bg-transparent text-transparent", src: "https://cdn.b3.fun/b3-coin-3d.png" }), _jsx("div", { className: "absolute inset-0 rounded-[50%] border border-white/20" })] })] }), _jsxs(motion.div, { initial: false, animate: {
|
|
370
|
+
}, transition: { duration: 0.3, delay: 0, ease: "easeInOut" }, className: `flex justify-center ${isActive ? "mb-4" : ""}`, children: _jsx("img", { alt: "B3 Token", loading: "lazy", width: "64", height: "64", decoding: "async", className: "rounded-full", src: "https://cdn.b3.fun/b3-coin-3d.png" }) }), _jsx(motion.div, { initial: false, animate: {
|
|
303
371
|
opacity: hasMounted ? 1 : 0,
|
|
304
372
|
y: hasMounted ? 0 : 20,
|
|
305
373
|
filter: hasMounted ? "blur(0px)" : "blur(10px)"
|
|
306
|
-
}, transition: { duration: 0.3, delay: 0.1, ease: "easeInOut" }, className: "text-center", children:
|
|
374
|
+
}, transition: { duration: 0.3, delay: 0.1, ease: "easeInOut" }, className: "text-center", children: isActive ? (_jsxs(_Fragment, { children: [_jsx("h2", { className: "font-sf-rounded text-as-primary mb-4 text-2xl font-bold", children: (() => {
|
|
375
|
+
const hasEnoughBalance = b3RawBalance && totalCost <= b3RawBalance;
|
|
376
|
+
return hasEnoughBalance || !debouncedQuantity ? "Buy Spins" : `Swap & Buy Spins`;
|
|
377
|
+
})() }), wheelInfo && (_jsxs("div", { className: "inline-flex items-center gap-2", children: [_jsx("div", { className: "bg-as-brand/10 border-as-brand/10 inline-flex items-center rounded-full border px-3 py-1", children: _jsxs("p", { className: "text-as-brand text-sm font-medium", children: [pricePerEntry, " $B3 per spin"] }) }), _jsx("div", { className: "bg-as-brand/10 border-as-brand/10 inline-flex items-center rounded-full border px-3 py-1", children: _jsxs("p", { className: "text-as-brand text-sm font-medium", children: [remainingEntries.toString(), " remaining"] }) })] }))] })) : (statusInfo && (_jsxs("div", { className: "text-center", children: [_jsx("p", { className: "text-as-primary text-lg font-semibold", children: statusInfo.title }), _jsx("p", { className: "text-as-primary/70 mt-2 text-sm", children: statusInfo.message })] }))) })] }), _jsx(motion.div, { initial: false, animate: {
|
|
307
378
|
opacity: hasMounted ? 1 : 0,
|
|
308
379
|
y: hasMounted ? 0 : 20,
|
|
309
380
|
filter: hasMounted ? "blur(0px)" : "blur(10px)"
|
|
310
|
-
}, transition: { duration: 0.3, delay: 0.2, ease: "easeInOut" }, className: "bg-b3-react-background w-full p-6", children: [
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
381
|
+
}, transition: { duration: 0.3, delay: 0.2, ease: "easeInOut" }, className: "bg-b3-react-background w-full p-6", children: isActive ? (_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("p", { className: "text-as-primary/70 text-sm font-medium", children: "Number of spins" }), _jsxs("span", { className: "text-as-primary/50 flex items-center gap-1 text-sm", children: ["Available: ", isBalanceLoading ? _jsx(Loader2, { className: "h-3 w-3 animate-spin" }) : `${b3Balance} B3`] })] }), _jsxs("div", { className: "relative", children: [_jsx(Input, { onFocus: onFocusQuantityInput, type: "text", placeholder: "1", value: displayQuantity, onChange: e => validateAndSetQuantity(e.target.value), className: `h-14 px-4 pr-20 text-lg ${!isQuantityValid && displayQuantity ? "border-as-red" : "border-b3-react-border"}` }), _jsx("div", { className: "font-pack absolute right-4 top-1/2 -translate-y-1/2 text-lg font-medium text-blue-500/70", children: displayQuantity === "1" ? "Spin" : "Spins" })] }), !isQuantityValid && displayQuantity && _jsx("p", { className: "text-as-red text-sm", children: validationError }), _jsx("div", { className: "bg-as-on-surface-2/30 rounded-lg border border-white/10 p-4 backdrop-blur-sm", children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-as-primary/70 text-sm font-medium", children: "Total Cost:" }), _jsx("div", { className: "flex items-center gap-2", children: _jsxs("span", { className: "text-as-primary text-lg font-bold", children: [displayQuantity && isQuantityValid ? formatUnits(totalCost, 18) : "0", " B3"] }) })] }) }), _jsx("div", { className: "mt-4", children: (() => {
|
|
382
|
+
const hasEnoughBalance = b3RawBalance && totalCost <= b3RawBalance;
|
|
383
|
+
if (!hasEnoughBalance && debouncedQuantity) {
|
|
384
|
+
return (_jsxs("div", { className: "bg-as-brand/10 flex flex-col items-center gap-2 rounded-lg p-4 pb-5", children: [_jsxs("div", { className: "flex items-center justify-center gap-2", children: [_jsx("span", { className: "text-as-primary text-sm font-semibold", children: "Swap & buy from any token" }), _jsxs(TextLoop, { children: [_jsx(EthIcon, { className: "h-8 w-8" }), _jsx(SolIcon, { className: "h-8 w-8" }), _jsx(UsdcIcon, { className: "h-8 w-8" })] }), _jsx(ArrowRight, { className: "text-as-primary h-4 w-4" }), _jsx("img", { src: "https://cdn.b3.fun/b3-coin-3d.png", className: "h-7 w-7", alt: "B3 Token" })] }), _jsx("p", { className: "text-as-primary/50 text-sm font-medium", children: "No problem, we'll help you swap to B3 for your spins!" })] }));
|
|
385
|
+
}
|
|
386
|
+
})() }), _jsx(Button, { onClick: confirmQuantity, disabled: !isQuantityValid || !displayQuantity || isBuying || isTxPending, className: "bg-as-brand hover:bg-as-brand/90 text-as-primary mt-4 h-14 w-full rounded-xl text-lg font-medium", children: isBuying ? "Buying..." : isTxPending ? "Confirming..." : "Continue" })] })) : null })] }) }));
|
|
314
387
|
}
|
|
315
388
|
// AnySpend flow for when user needs to swap to B3
|
|
316
389
|
const encodedData = generateEncodedDataForBuyEntriesAndSpin(address || "", userSpinQuantity);
|
|
@@ -26,5 +26,9 @@ export function OrderHistoryItem({ order, onSelectOrder, mode }) {
|
|
|
26
26
|
: order.payload.expectedDstAmount;
|
|
27
27
|
const { text: orderStatusText, status: orderDisplayStatus } = getStatusDisplay(order);
|
|
28
28
|
const isSmallView = useIsMobile() || mode === "modal";
|
|
29
|
-
return (_jsxs("div", { className: cn("bg-as-light-brand/20 rounded-lg border p-4", onSelectOrder && "hover:bg-as-light-brand/30 hover:border-as-brand cursor-pointer transition-colors"), onClick: () => onSelectOrder?.(order.id), children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx(Badge, { className: cn("px-3 py-1 text-xs", orderDisplayStatus === "processing" && "bg-yellow-500/10 text-yellow-500", orderDisplayStatus === "success" && "bg-green-500/10 text-green-500", orderDisplayStatus === "failure" && "bg-red-500/10 text-red-500"), children: orderStatusText }), _jsx("div", { className: "flex items-center gap-2", children: _jsx("span", { className: "text-nano label-style text-as-primary/30", children: _jsx(TimeAgo, { date: new Date(order.createdAt) }) }) })] }), order.oneClickBuyUrl ? (_jsx("div", { className: "mb-3 mt-4 flex items-center gap-1", children: _jsxs("div", { className: "bg-b3-react-background flex flex-1 flex-col gap-1 rounded-lg border p-4 px-5", children: [_jsxs("h3", { className: "text-as-primary/50 flex items-center gap-2 text-xl font-semibold", children: [_jsxs("span", { children: ["Buy ", _jsxs("span", { className: "text-as-primary", children: ["$", formatTokenAmount(BigInt(order.srcAmount), order.metadata.srcToken.decimals)] }), ` of`] }), _jsxs("span", { className: "text-as-primary flex items-center gap-2", children: [nft ? (_jsx("img", { src: nft.imageUrl, alt: nft.name, className: "h-6 w-6" })) : tournament ? (_jsx("img", { src: tournament.imageUrl, alt: tournament.name, className: "h-6 w-6" })) : (_jsx("img", { src: dstToken.metadata.logoURI, alt: dstToken.symbol, className: "h-6 w-6" })), nft ? nft.name : tournament ? tournament.name : dstToken.symbol] }), _jsxs("span", { className: "flex items-center gap-2", children: [` on `, _jsxs("span", { className: "text-as-primary flex items-center gap-2", children: [_jsx("img", { src: ALL_CHAINS[order.dstChain]?.logoUrl, alt: getChainName(order.dstChain), className: "h-4" }), order.dstChain !== b3.id && getChainName(order.dstChain)] })] })] }), _jsxs("p", { className: "label-style text-as-primary/30 mt-1 flex items-center gap-2 text-xs", children: ["Paying via", " ", _jsx("img", { src: "https://cdn.b3.fun/coinbase-wordmark-blue.svg", alt: "Coinbase", className: "-mt-1 h-3" })] })] }) })) : (_jsxs("div", { className: cn("mb-3 mt-4 flex items-center gap-1", isSmallView && "flex-col"), children: [_jsxs("div", { className: "bg-b3-react-background flex w-full flex-1 flex-col gap-1 overflow-hidden rounded-lg border p-4 px-5", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("img", { src: order.metadata.srcToken.metadata.logoURI, alt: order.metadata.srcToken.symbol, className: "h-6 w-6 rounded-full" }), _jsxs("div", { className: "text-as-primary flex items-center gap-2 overflow-hidden text-ellipsis whitespace-nowrap text-xl font-semibold", children: [formatTokenAmount(BigInt(order.srcAmount), order.metadata.srcToken.decimals), " ", order.metadata.srcToken.symbol] })] }), _jsxs("div", { className: "label-style text-as-primary/50 flex items-center gap-2 text-sm", children: ["from", _jsx("img", { src: ALL_CHAINS[order.srcChain]?.logoUrl, alt: getChainName(order.srcChain), className: cn("h-4", order.srcChain !== b3.id && "w-4 rounded-full", order.srcChain === b3.id && "h-3") }), getChainName(order.srcChain)] })] }), _jsx("div", { className: cn("h-8 w-8 shrink-0 -rotate-90 opacity-30", isSmallView && "rotate-0"), children: _jsx(ChevronDown, { className: "h-8 w-8" }) }), _jsxs("div", { className: "bg-b3-react-background flex w-full flex-1 flex-col gap-1 overflow-hidden rounded-lg border p-4 px-5", children: [_jsx("div", { className: "flex items-center gap-2", children: nft ? (_jsxs(_Fragment, { children: [_jsx("img", { src: nft.imageUrl, alt: nft.name, className: "h-6 w-6 rounded-full" }), _jsx("div", { className: "text-as-primary overflow-hidden text-ellipsis whitespace-nowrap text-xl font-semibold", children: nft.name })] })) : tournament ? (_jsxs(_Fragment, { children: [_jsx("img", { src: tournament.imageUrl, alt: tournament.name, className: "h-6 w-6 rounded-full" }), _jsx("div", { className: "text-as-primary overflow-hidden text-ellipsis whitespace-nowrap text-xl font-semibold", children: tournament.name })] })) : (_jsxs(_Fragment, { children: [_jsx("img", { src: dstToken.metadata.logoURI, alt: dstToken.symbol, className: "h-6 w-6 rounded-full" }), _jsxs("div", { className: "text-as-primary overflow-hidden text-ellipsis whitespace-nowrap text-xl font-semibold", children: [formatTokenAmount(actualDstAmount
|
|
29
|
+
return (_jsxs("div", { className: cn("bg-as-light-brand/20 rounded-lg border p-4", onSelectOrder && "hover:bg-as-light-brand/30 hover:border-as-brand cursor-pointer transition-colors"), onClick: () => onSelectOrder?.(order.id), children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx(Badge, { className: cn("px-3 py-1 text-xs", orderDisplayStatus === "processing" && "bg-yellow-500/10 text-yellow-500", orderDisplayStatus === "success" && "bg-green-500/10 text-green-500", orderDisplayStatus === "failure" && "bg-red-500/10 text-red-500"), children: orderStatusText }), _jsx("div", { className: "flex items-center gap-2", children: _jsx("span", { className: "text-nano label-style text-as-primary/30", children: _jsx(TimeAgo, { date: new Date(order.createdAt) }) }) })] }), order.oneClickBuyUrl ? (_jsx("div", { className: "mb-3 mt-4 flex items-center gap-1", children: _jsxs("div", { className: "bg-b3-react-background flex flex-1 flex-col gap-1 rounded-lg border p-4 px-5", children: [_jsxs("h3", { className: "text-as-primary/50 flex items-center gap-2 text-xl font-semibold", children: [_jsxs("span", { children: ["Buy ", _jsxs("span", { className: "text-as-primary", children: ["$", formatTokenAmount(BigInt(order.srcAmount), order.metadata.srcToken.decimals)] }), ` of`] }), _jsxs("span", { className: "text-as-primary flex items-center gap-2", children: [nft ? (_jsx("img", { src: nft.imageUrl, alt: nft.name, className: "h-6 w-6" })) : tournament ? (_jsx("img", { src: tournament.imageUrl, alt: tournament.name, className: "h-6 w-6" })) : (_jsx("img", { src: dstToken.metadata.logoURI, alt: dstToken.symbol, className: "h-6 w-6" })), nft ? nft.name : tournament ? tournament.name : dstToken.symbol] }), _jsxs("span", { className: "flex items-center gap-2", children: [` on `, _jsxs("span", { className: "text-as-primary flex items-center gap-2", children: [_jsx("img", { src: ALL_CHAINS[order.dstChain]?.logoUrl, alt: getChainName(order.dstChain), className: "h-4" }), order.dstChain !== b3.id && getChainName(order.dstChain)] })] })] }), _jsxs("p", { className: "label-style text-as-primary/30 mt-1 flex items-center gap-2 text-xs", children: ["Paying via", " ", _jsx("img", { src: "https://cdn.b3.fun/coinbase-wordmark-blue.svg", alt: "Coinbase", className: "-mt-1 h-3" })] })] }) })) : (_jsxs("div", { className: cn("mb-3 mt-4 flex items-center gap-1", isSmallView && "flex-col"), children: [_jsxs("div", { className: "bg-b3-react-background flex w-full flex-1 flex-col gap-1 overflow-hidden rounded-lg border p-4 px-5", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("img", { src: order.metadata.srcToken.metadata.logoURI, alt: order.metadata.srcToken.symbol, className: "h-6 w-6 rounded-full" }), _jsxs("div", { className: "text-as-primary flex items-center gap-2 overflow-hidden text-ellipsis whitespace-nowrap text-xl font-semibold", children: [formatTokenAmount(BigInt(order.srcAmount), order.metadata.srcToken.decimals), " ", order.metadata.srcToken.symbol] })] }), _jsxs("div", { className: "label-style text-as-primary/50 flex items-center gap-2 text-sm", children: ["from", _jsx("img", { src: ALL_CHAINS[order.srcChain]?.logoUrl, alt: getChainName(order.srcChain), className: cn("h-4", order.srcChain !== b3.id && "w-4 rounded-full", order.srcChain === b3.id && "h-3") }), getChainName(order.srcChain)] })] }), _jsx("div", { className: cn("h-8 w-8 shrink-0 -rotate-90 opacity-30", isSmallView && "rotate-0"), children: _jsx(ChevronDown, { className: "h-8 w-8" }) }), _jsxs("div", { className: "bg-b3-react-background flex w-full flex-1 flex-col gap-1 overflow-hidden rounded-lg border p-4 px-5", children: [_jsx("div", { className: "flex items-center gap-2", children: nft ? (_jsxs(_Fragment, { children: [_jsx("img", { src: nft.imageUrl, alt: nft.name, className: "h-6 w-6 rounded-full" }), _jsx("div", { className: "text-as-primary overflow-hidden text-ellipsis whitespace-nowrap text-xl font-semibold", children: nft.name })] })) : tournament ? (_jsxs(_Fragment, { children: [_jsx("img", { src: tournament.imageUrl, alt: tournament.name, className: "h-6 w-6 rounded-full" }), _jsx("div", { className: "text-as-primary overflow-hidden text-ellipsis whitespace-nowrap text-xl font-semibold", children: tournament.name })] })) : (_jsxs(_Fragment, { children: [_jsx("img", { src: dstToken.metadata.logoURI, alt: dstToken.symbol, className: "h-6 w-6 rounded-full" }), _jsxs("div", { className: "text-as-primary overflow-hidden text-ellipsis whitespace-nowrap text-xl font-semibold", children: [formatTokenAmount(actualDstAmount
|
|
30
|
+
? BigInt(actualDstAmount)
|
|
31
|
+
: expectedDstAmount
|
|
32
|
+
? BigInt(expectedDstAmount)
|
|
33
|
+
: BigInt(0), dstToken.decimals), " ", dstToken.symbol] })] })) }), _jsxs("div", { className: "label-style text-as-primary/50 flex items-center gap-2 text-sm", children: ["to", _jsx("img", { src: ALL_CHAINS[order.dstChain]?.logoUrl, alt: getChainName(order.dstChain), className: cn("h-4", order.dstChain !== b3.id && "w-4 rounded-full", order.dstChain === b3.id && "h-3") }), getChainName(order.dstChain)] })] })] })), _jsx("div", { className: "flex items-center justify-end", children: _jsxs(Button, { variant: "link", size: "sm", className: "h-auto", onClick: () => onSelectOrder?.(order.id), children: [orderDisplayStatus === "processing" ? "Proceed with payment" : "Details", " ", _jsx(ArrowRight, { className: "ml-2 h-3 w-3" })] }) })] }, `anyspend-${order.id}`));
|
|
30
34
|
}
|
|
@@ -11,7 +11,7 @@ export function TokenBalance({ token, walletAddress, onChangeInput }) {
|
|
|
11
11
|
return;
|
|
12
12
|
// Calculate the amount based on percentage of balance
|
|
13
13
|
// Multiply first, then divide to avoid BigInt truncation
|
|
14
|
-
const amount = percentage === 100 ? rawBalance : (rawBalance * BigInt(percentage)) /
|
|
14
|
+
const amount = percentage === 100 ? rawBalance : (rawBalance * BigInt(percentage)) / BigInt(100);
|
|
15
15
|
onChangeInput(formatUnits(amount, token.decimals));
|
|
16
16
|
};
|
|
17
17
|
return (_jsx("div", { className: "flex h-7 items-center justify-end gap-1", children: !isLoading && (_jsxs(_Fragment, { children: [_jsx("div", { className: "text-as-primary/50 inline-flex rounded-lg text-sm", children: rawBalance ? `Balance: ${formattedBalance}` : `Balance: 0` }), !!rawBalance && (_jsxs(_Fragment, { children: [_jsx("button", { onClick: () => handlePercentageClick(20), className: "text-as-primary/50 bg-as-on-surface-2 hover:bg-as-on-surface-3 inline-flex rounded-lg px-2 py-1 text-xs transition-colors sm:hidden", children: "20%" }), _jsx("button", { onClick: () => handlePercentageClick(50), className: "text-as-primary/50 bg-as-on-surface-2 hover:bg-as-on-surface-3 inline-flex rounded-lg px-2 py-1 text-xs transition-colors", children: "50%" }), _jsx("button", { onClick: () => handlePercentageClick(100), className: "text-as-primary/50 bg-as-on-surface-2 hover:bg-as-on-surface-3 inline-flex rounded-lg px-2 py-1 text-xs transition-colors", children: "MAX" })] }))] })) }, `balance-${token.address}-${token.chainId}`));
|
|
@@ -244,6 +244,9 @@ export function getPaymentUrl(address, amount, currency) {
|
|
|
244
244
|
return `ethereum:${address}`;
|
|
245
245
|
}
|
|
246
246
|
export function getExplorerTxUrl(chainId, txHash) {
|
|
247
|
+
if (chainId === b3.id) {
|
|
248
|
+
return "https://explorer.b3.fun/b3/tx/" + txHash;
|
|
249
|
+
}
|
|
247
250
|
if (EVM_CHAINS[chainId]) {
|
|
248
251
|
return EVM_CHAINS[chainId].viem.blockExplorers?.default.url + "/tx/" + txHash;
|
|
249
252
|
}
|
|
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { AnySpend, AnySpendBuySpin, AnySpendNFT, AnySpendStakeB3, AnySpendTournament, OrderHistory } from "../../../anyspend/react";
|
|
3
3
|
import { useIsMobile, useModalStore } from "../../../global-account/react";
|
|
4
4
|
import { debugB3React } from "../../../shared/utils/debug";
|
|
5
|
-
import { useB3 } from "./B3Provider";
|
|
5
|
+
import { useB3 } from "./B3Provider/useB3";
|
|
6
6
|
import { ManageAccount } from "./ManageAccount/ManageAccount";
|
|
7
7
|
import { RequestPermissions } from "./RequestPermissions/RequestPermissions";
|
|
8
8
|
import { SignInWithB3Flow } from "./SignInWithB3/SignInWithB3Flow";
|
package/dist/esm/global-account/react/components/{B3Provider.d.ts → B3Provider/B3Provider.d.ts}
RENAMED
|
@@ -1,34 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { Account, Wallet } from "thirdweb/wallets";
|
|
1
|
+
import { PermissionsConfig } from "../../../../global-account/types/permissions";
|
|
2
|
+
import { Account } from "thirdweb/wallets";
|
|
4
3
|
import "@reservoir0x/relay-kit-ui/styles.css";
|
|
4
|
+
import { B3ContextType } from "./types";
|
|
5
5
|
export declare const wagmiConfig: import("wagmi").Config<readonly [import("viem").Chain, ...import("viem").Chain[]], any, readonly import("wagmi").CreateConnectorFn[]>;
|
|
6
|
-
/**
|
|
7
|
-
* Context type for B3Provider
|
|
8
|
-
*/
|
|
9
|
-
export interface B3ContextType {
|
|
10
|
-
account?: Account;
|
|
11
|
-
automaticallySetFirstEoa: boolean;
|
|
12
|
-
user?: User;
|
|
13
|
-
setAccount: (account: Account) => void;
|
|
14
|
-
setWallet: (wallet: Wallet) => void;
|
|
15
|
-
wallet?: Wallet;
|
|
16
|
-
setUser: (user?: User) => void;
|
|
17
|
-
initialized: boolean;
|
|
18
|
-
ready: boolean;
|
|
19
|
-
environment?: "development" | "production";
|
|
20
|
-
defaultPermissions?: PermissionsConfig;
|
|
21
|
-
theme: "light" | "dark";
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Context for B3 provider
|
|
25
|
-
*/
|
|
26
|
-
export declare const B3Context: import("react").Context<B3ContextType>;
|
|
27
|
-
/**
|
|
28
|
-
* Hook to access the B3 context
|
|
29
|
-
* @throws Error if used outside a B3Provider
|
|
30
|
-
*/
|
|
31
|
-
export declare function useB3(): B3ContextType;
|
|
32
6
|
/**
|
|
33
7
|
* Main B3Provider component
|
|
34
8
|
*/
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { supportedChains } from "
|
|
2
|
+
import { supportedChains } from "../../../../shared/constants/chains/supported";
|
|
3
3
|
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
4
|
-
import {
|
|
4
|
+
import { useEffect, useState } from "react";
|
|
5
5
|
import { Toaster } from "sonner";
|
|
6
6
|
import { ThirdwebProvider, useActiveAccount, useConnectedWallets, useSetActiveWallet } from "thirdweb/react";
|
|
7
7
|
import { createConfig, http, WagmiProvider } from "wagmi";
|
|
8
|
-
import { RelayKitProviderWrapper } from "
|
|
9
|
-
import { StyleRoot } from "
|
|
8
|
+
import { RelayKitProviderWrapper } from "../RelayKitProviderWrapper";
|
|
9
|
+
import { StyleRoot } from "../StyleRoot";
|
|
10
10
|
import "@reservoir0x/relay-kit-ui/styles.css";
|
|
11
|
+
import { B3Context } from "./types";
|
|
11
12
|
/**
|
|
12
13
|
* Default permissions configuration for B3 provider
|
|
13
14
|
*/
|
|
@@ -21,34 +22,6 @@ export const wagmiConfig = createConfig({
|
|
|
21
22
|
chains: [supportedChains[0], ...supportedChains.slice(1)],
|
|
22
23
|
transports: Object.fromEntries(supportedChains.map(chain => [chain.id, http()]))
|
|
23
24
|
});
|
|
24
|
-
/**
|
|
25
|
-
* Context for B3 provider
|
|
26
|
-
*/
|
|
27
|
-
export const B3Context = createContext({
|
|
28
|
-
account: undefined,
|
|
29
|
-
automaticallySetFirstEoa: false,
|
|
30
|
-
user: undefined,
|
|
31
|
-
setAccount: () => { },
|
|
32
|
-
setWallet: () => { },
|
|
33
|
-
wallet: undefined,
|
|
34
|
-
setUser: () => { },
|
|
35
|
-
initialized: false,
|
|
36
|
-
ready: false,
|
|
37
|
-
environment: "development",
|
|
38
|
-
theme: "light"
|
|
39
|
-
});
|
|
40
|
-
/**
|
|
41
|
-
* Hook to access the B3 context
|
|
42
|
-
* @throws Error if used outside a B3Provider
|
|
43
|
-
*/
|
|
44
|
-
export function useB3() {
|
|
45
|
-
const context = useContext(B3Context);
|
|
46
|
-
if (!context.initialized) {
|
|
47
|
-
throw new Error("useB3 must be used within a B3Provider");
|
|
48
|
-
}
|
|
49
|
-
// Return a stable reference
|
|
50
|
-
return useMemo(() => context, [context]);
|
|
51
|
-
}
|
|
52
25
|
// Create queryClient instance
|
|
53
26
|
const queryClient = new QueryClient();
|
|
54
27
|
/**
|
|
@@ -1,29 +1,6 @@
|
|
|
1
|
-
import { PermissionsConfig } from "
|
|
1
|
+
import { PermissionsConfig } from "../../../../global-account/types/permissions";
|
|
2
2
|
import { Account } from "thirdweb/wallets";
|
|
3
|
-
import {
|
|
4
|
-
/**
|
|
5
|
-
* Context type for B3Provider
|
|
6
|
-
*/
|
|
7
|
-
export interface B3ContextType {
|
|
8
|
-
account?: Account;
|
|
9
|
-
user?: User;
|
|
10
|
-
setAccount: (account: Account) => void;
|
|
11
|
-
setUser: (user?: User) => void;
|
|
12
|
-
initialized: boolean;
|
|
13
|
-
ready: boolean;
|
|
14
|
-
environment?: "development" | "production";
|
|
15
|
-
defaultPermissions?: PermissionsConfig;
|
|
16
|
-
theme: "light" | "dark";
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Context for B3 provider
|
|
20
|
-
*/
|
|
21
|
-
export declare const B3Context: import("react").Context<B3ContextType>;
|
|
22
|
-
/**
|
|
23
|
-
* Hook to access the B3 context
|
|
24
|
-
* @throws Error if used outside a B3Provider
|
|
25
|
-
*/
|
|
26
|
-
export declare function useB3(): B3ContextType;
|
|
3
|
+
import { B3ContextType } from "./types";
|
|
27
4
|
/**
|
|
28
5
|
* Main B3Provider component
|
|
29
6
|
*/
|