@b3dotfun/sdk 0.0.1-alpha.23 → 0.0.1-alpha.4
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/dist/cjs/anyspend/react/components/AnySpend.d.ts +1 -2
- package/dist/cjs/anyspend/react/components/AnySpend.js +4 -4
- package/dist/cjs/anyspend/react/components/AnySpendBuySpin.d.ts +1 -2
- package/dist/cjs/anyspend/react/components/AnySpendBuySpin.js +51 -124
- package/dist/cjs/anyspend/utils/chain.js +0 -3
- package/dist/cjs/global-account/react/components/B3DynamicModal.js +2 -2
- package/dist/{esm/global-account/react/components/B3Provider → cjs/global-account/react/components}/B3Provider.d.ts +29 -3
- package/dist/cjs/global-account/react/components/{B3Provider/B3Provider.js → B3Provider.js} +34 -6
- package/dist/cjs/global-account/react/components/{B3Provider/B3Provider.native.d.ts → B3Provider.native.d.ts} +25 -2
- package/dist/cjs/global-account/react/components/{B3Provider/B3Provider.native.js → B3Provider.native.js} +28 -5
- package/dist/cjs/global-account/react/components/StyleRoot.js +2 -2
- package/dist/cjs/global-account/react/components/index.d.ts +6 -8
- package/dist/cjs/global-account/react/components/index.js +16 -18
- package/dist/cjs/global-account/react/stores/useModalStore.d.ts +0 -2
- 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 +3 -4
- package/dist/cjs/shared/constants/chains/supported.js +1 -3
- package/dist/cjs/shared/utils/chains.js +0 -4
- package/dist/esm/anyspend/react/components/AnySpend.d.ts +1 -2
- package/dist/esm/anyspend/react/components/AnySpend.js +4 -4
- package/dist/esm/anyspend/react/components/AnySpendBuySpin.d.ts +1 -2
- package/dist/esm/anyspend/react/components/AnySpendBuySpin.js +51 -124
- package/dist/esm/anyspend/utils/chain.js +0 -3
- package/dist/esm/global-account/react/components/B3DynamicModal.js +1 -1
- package/dist/{cjs/global-account/react/components/B3Provider → esm/global-account/react/components}/B3Provider.d.ts +29 -3
- package/dist/esm/global-account/react/components/{B3Provider/B3Provider.js → B3Provider.js} +32 -5
- package/dist/esm/global-account/react/components/{B3Provider/B3Provider.native.d.ts → B3Provider.native.d.ts} +25 -2
- package/dist/esm/global-account/react/components/{B3Provider/B3Provider.native.js → B3Provider.native.js} +26 -5
- package/dist/esm/global-account/react/components/StyleRoot.js +1 -1
- package/dist/esm/global-account/react/components/index.d.ts +6 -8
- package/dist/esm/global-account/react/components/index.js +5 -7
- package/dist/esm/global-account/react/stores/useModalStore.d.ts +0 -2
- 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 +3 -4
- package/dist/esm/shared/constants/chains/supported.js +0 -2
- package/dist/esm/shared/utils/chains.js +0 -4
- package/dist/styles/index.css +1 -1
- package/dist/types/anyspend/react/components/AnySpend.d.ts +1 -2
- package/dist/types/anyspend/react/components/AnySpendBuySpin.d.ts +1 -2
- package/dist/types/global-account/react/components/{B3Provider/B3Provider.d.ts → B3Provider.d.ts} +28 -2
- package/dist/types/global-account/react/components/{B3Provider/B3Provider.native.d.ts → B3Provider.native.d.ts} +24 -1
- package/dist/types/global-account/react/components/index.d.ts +6 -8
- package/dist/types/global-account/react/stores/useModalStore.d.ts +0 -2
- 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 +3 -4
- package/package.json +11 -25
- package/src/anyspend/react/components/AnySpend.tsx +5 -6
- package/src/anyspend/react/components/AnySpendBuySpin.tsx +180 -233
- package/src/anyspend/utils/chain.ts +0 -3
- package/src/global-account/react/components/B3DynamicModal.tsx +1 -1
- package/src/global-account/react/components/{B3Provider/B3Provider.native.tsx → B3Provider.native.tsx} +45 -4
- package/src/global-account/react/components/{B3Provider/B3Provider.tsx → B3Provider.tsx} +53 -4
- package/src/global-account/react/components/StyleRoot.tsx +1 -1
- package/src/global-account/react/components/index.ts +6 -8
- package/src/global-account/react/stores/useModalStore.ts +0 -2
- package/src/shared/constants/chains/supported.ts +0 -2
- package/src/shared/utils/chains.ts +1 -4
- package/dist/cjs/anyspend/index.native.d.ts +0 -13
- package/dist/cjs/anyspend/index.native.js +0 -35
- package/dist/cjs/global-account/react/components/B3Provider/types.d.ts +0 -25
- package/dist/cjs/global-account/react/components/B3Provider/types.js +0 -20
- package/dist/cjs/global-account/react/components/B3Provider/useB3.d.ts +0 -5
- package/dist/cjs/global-account/react/components/B3Provider/useB3.js +0 -17
- package/dist/cjs/global-account/react/index.native.d.ts +0 -7
- package/dist/cjs/global-account/react/index.native.js +0 -21
- package/dist/esm/anyspend/index.native.d.ts +0 -13
- package/dist/esm/anyspend/index.native.js +0 -19
- package/dist/esm/global-account/react/components/B3Provider/types.d.ts +0 -25
- package/dist/esm/global-account/react/components/B3Provider/types.js +0 -17
- package/dist/esm/global-account/react/components/B3Provider/useB3.d.ts +0 -5
- package/dist/esm/global-account/react/components/B3Provider/useB3.js +0 -14
- package/dist/esm/global-account/react/index.native.d.ts +0 -7
- package/dist/esm/global-account/react/index.native.js +0 -11
- package/dist/types/anyspend/index.native.d.ts +0 -13
- package/dist/types/global-account/react/components/B3Provider/types.d.ts +0 -25
- package/dist/types/global-account/react/components/B3Provider/useB3.d.ts +0 -5
- package/dist/types/global-account/react/index.native.d.ts +0 -7
- package/src/anyspend/index.native.ts +0 -24
- package/src/global-account/react/components/B3Provider/types.ts +0 -40
- package/src/global-account/react/components/B3Provider/useB3.ts +0 -17
- package/src/global-account/react/index.native.ts +0 -14
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { B3_TOKEN, OrderType } from "@b3dotfun/sdk/anyspend";
|
|
2
|
-
import { baseMainnet } from "@b3dotfun/sdk/shared/constants/chains/supported";
|
|
3
2
|
import { EthIcon } from "./icons/EthIcon";
|
|
4
3
|
import { SolIcon } from "./icons/SolIcon";
|
|
5
4
|
import { UsdcIcon } from "./icons/USDCIcon";
|
|
@@ -20,6 +19,7 @@ import { ArrowRight, Loader2 } from "lucide-react";
|
|
|
20
19
|
import { useCallback, useEffect, useState } from "react";
|
|
21
20
|
import { toast } from "sonner";
|
|
22
21
|
import { createPublicClient, encodeFunctionData, erc20Abi, formatUnits, http } from "viem";
|
|
22
|
+
import { base } from "viem/chains";
|
|
23
23
|
import { useAccount, useWaitForTransactionReceipt, useWriteContract } from "wagmi";
|
|
24
24
|
import { AnySpendCustom } from "./AnySpendCustom";
|
|
25
25
|
|
|
@@ -52,20 +52,6 @@ const SPIN_WHEEL_ABI = [
|
|
|
52
52
|
outputs: [],
|
|
53
53
|
stateMutability: "payable",
|
|
54
54
|
type: "function"
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
inputs: [],
|
|
58
|
-
name: "getWheelInfo",
|
|
59
|
-
outputs: [
|
|
60
|
-
{ internalType: "address", name: "creator_", type: "address" },
|
|
61
|
-
{ internalType: "uint256", name: "startTime_", type: "uint256" },
|
|
62
|
-
{ internalType: "uint256", name: "endTime_", type: "uint256" },
|
|
63
|
-
{ internalType: "uint256", name: "totalPrizesAvailable_", type: "uint256" },
|
|
64
|
-
{ internalType: "uint256", name: "prizesRequestedCount_", type: "uint256" },
|
|
65
|
-
{ internalType: "enum SpinWheelV2.WheelState", name: "state_", type: "uint8" }
|
|
66
|
-
],
|
|
67
|
-
stateMutability: "view",
|
|
68
|
-
type: "function"
|
|
69
55
|
}
|
|
70
56
|
] as const;
|
|
71
57
|
|
|
@@ -76,37 +62,6 @@ interface PaymentConfig {
|
|
|
76
62
|
entryModule: string;
|
|
77
63
|
}
|
|
78
64
|
|
|
79
|
-
interface WheelInfo {
|
|
80
|
-
creator_: string;
|
|
81
|
-
startTime_: bigint;
|
|
82
|
-
endTime_: bigint;
|
|
83
|
-
totalPrizesAvailable_: bigint;
|
|
84
|
-
prizesRequestedCount_: bigint;
|
|
85
|
-
state_: number;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
type WheelStatus = "not_started" | "active" | "ended" | "sold_out";
|
|
89
|
-
|
|
90
|
-
function getWheelStatus(wheelInfo: WheelInfo): WheelStatus {
|
|
91
|
-
const now = BigInt(Math.floor(Date.now() / 1000));
|
|
92
|
-
console.log("@@anyspend-buy-spin:now:", now);
|
|
93
|
-
console.log("@@anyspend-buy-spin:wheelInfo:", wheelInfo);
|
|
94
|
-
|
|
95
|
-
if (now < wheelInfo.startTime_) {
|
|
96
|
-
return "not_started";
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
if (now > wheelInfo.endTime_) {
|
|
100
|
-
return "ended";
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
if (wheelInfo.totalPrizesAvailable_ <= wheelInfo.prizesRequestedCount_) {
|
|
104
|
-
return "sold_out";
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
return "active";
|
|
108
|
-
}
|
|
109
|
-
|
|
110
65
|
function generateEncodedDataForBuyEntriesAndSpin(user: string, quantity: string): string {
|
|
111
66
|
invariant(BigInt(quantity) > 0, "Quantity must be greater than zero");
|
|
112
67
|
console.log("@@anyspend-buy-spin:encoded-data:", { user, quantity });
|
|
@@ -119,7 +74,7 @@ function generateEncodedDataForBuyEntriesAndSpin(user: string, quantity: string)
|
|
|
119
74
|
}
|
|
120
75
|
|
|
121
76
|
const basePublicClient = createPublicClient({
|
|
122
|
-
chain:
|
|
77
|
+
chain: base,
|
|
123
78
|
transport: http()
|
|
124
79
|
});
|
|
125
80
|
|
|
@@ -130,7 +85,6 @@ export function AnySpendBuySpin({
|
|
|
130
85
|
spinwheelContractAddress,
|
|
131
86
|
chainId,
|
|
132
87
|
recipientAddress,
|
|
133
|
-
prefillQuantity,
|
|
134
88
|
onSuccess
|
|
135
89
|
}: {
|
|
136
90
|
isMainnet?: boolean;
|
|
@@ -139,7 +93,6 @@ export function AnySpendBuySpin({
|
|
|
139
93
|
spinwheelContractAddress: string;
|
|
140
94
|
chainId: number;
|
|
141
95
|
recipientAddress: string;
|
|
142
|
-
prefillQuantity?: string;
|
|
143
96
|
onSuccess?: (txHash?: string) => void;
|
|
144
97
|
}) {
|
|
145
98
|
const hasMounted = useHasMounted();
|
|
@@ -149,7 +102,6 @@ export function AnySpendBuySpin({
|
|
|
149
102
|
const [paymentConfig, setPaymentConfig] = useState<PaymentConfig | null>(null);
|
|
150
103
|
const [isLoadingConfig, setIsLoadingConfig] = useState(true);
|
|
151
104
|
const [configError, setConfigError] = useState<string>("");
|
|
152
|
-
const [wheelInfo, setWheelInfo] = useState<WheelInfo | null>(null);
|
|
153
105
|
|
|
154
106
|
// Fetch B3 token balance
|
|
155
107
|
const {
|
|
@@ -168,34 +120,24 @@ export function AnySpendBuySpin({
|
|
|
168
120
|
// State for direct buying flow (when user has B3 tokens)
|
|
169
121
|
const [isBuying, setIsBuying] = useState(false);
|
|
170
122
|
const [buyingTxHash, setBuyingTxHash] = useState<string>("");
|
|
171
|
-
const
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
error: txError
|
|
176
|
-
} = useWaitForTransactionReceipt({
|
|
123
|
+
const [showSuccessModal, setShowSuccessModal] = useState(false);
|
|
124
|
+
|
|
125
|
+
// Wait for transaction confirmation
|
|
126
|
+
const { isLoading: isTxPending, isSuccess: isTxSuccess } = useWaitForTransactionReceipt({
|
|
177
127
|
hash: buyingTxHash as `0x${string}`,
|
|
178
128
|
query: {
|
|
179
129
|
structuralSharing: false
|
|
180
130
|
}
|
|
181
131
|
});
|
|
182
132
|
|
|
183
|
-
//
|
|
133
|
+
// Show success modal when transaction is confirmed
|
|
184
134
|
useEffect(() => {
|
|
185
|
-
if (
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
setB3ModalOpen(false);
|
|
189
|
-
onSuccess?.(buyingTxHash);
|
|
190
|
-
toast.success("Spin purchase transaction confirmed!");
|
|
191
|
-
setIsBuying(false);
|
|
192
|
-
} else if (isTxError) {
|
|
193
|
-
console.error("@@anyspend-buy-spin:tx-error:", txError);
|
|
194
|
-
toast.error("Transaction failed. Please try again.");
|
|
195
|
-
setB3ModalOpen(false);
|
|
135
|
+
if (isTxSuccess && buyingTxHash) {
|
|
136
|
+
setShowAmountPrompt(false);
|
|
137
|
+
setShowSuccessModal(true);
|
|
196
138
|
setIsBuying(false);
|
|
197
139
|
}
|
|
198
|
-
}, [isTxSuccess,
|
|
140
|
+
}, [isTxSuccess, buyingTxHash]);
|
|
199
141
|
|
|
200
142
|
// Spin quantity state
|
|
201
143
|
const [userSpinQuantity, setUserSpinQuantity] = useState<string>("");
|
|
@@ -204,21 +146,12 @@ export function AnySpendBuySpin({
|
|
|
204
146
|
const [validationError, setValidationError] = useState<string>("");
|
|
205
147
|
const [displayQuantity, setDisplayQuantity] = useState<string>("");
|
|
206
148
|
const [debouncedQuantity, setDebouncedQuantity] = useState<string>("");
|
|
207
|
-
const [debouncedUserSpinQuantity, setDebouncedUserSpinQuantity] = useState<string>("");
|
|
208
|
-
|
|
209
|
-
useEffect(() => {
|
|
210
|
-
if (prefillQuantity && wheelInfo) {
|
|
211
|
-
const remainingSpins = wheelInfo.totalPrizesAvailable_ - wheelInfo.prizesRequestedCount_;
|
|
212
|
-
const adjustedQuantity = BigInt(prefillQuantity) > remainingSpins ? remainingSpins.toString() : prefillQuantity;
|
|
213
|
-
validateAndSetQuantity(adjustedQuantity);
|
|
214
|
-
}
|
|
215
|
-
}, [prefillQuantity, wheelInfo]);
|
|
216
149
|
|
|
217
150
|
// Calculate total cost
|
|
218
151
|
const totalCost =
|
|
219
152
|
paymentConfig && userSpinQuantity ? paymentConfig.pricePerEntry * BigInt(userSpinQuantity) : BigInt(0);
|
|
220
153
|
|
|
221
|
-
// Fetch payment configuration
|
|
154
|
+
// Fetch payment configuration
|
|
222
155
|
const fetchPaymentConfig = useCallback(async () => {
|
|
223
156
|
if (!basePublicClient || !spinwheelContractAddress) return;
|
|
224
157
|
|
|
@@ -228,7 +161,7 @@ export function AnySpendBuySpin({
|
|
|
228
161
|
|
|
229
162
|
console.log("@@anyspend-buy-spin:fetch-config:", { spinwheelContractAddress, chainId });
|
|
230
163
|
|
|
231
|
-
const [config, entryModuleAddress
|
|
164
|
+
const [config, entryModuleAddress] = await Promise.all([
|
|
232
165
|
basePublicClient.readContract({
|
|
233
166
|
address: spinwheelContractAddress as `0x${string}`,
|
|
234
167
|
abi: SPIN_WHEEL_ABI,
|
|
@@ -238,11 +171,6 @@ export function AnySpendBuySpin({
|
|
|
238
171
|
address: spinwheelContractAddress as `0x${string}`,
|
|
239
172
|
abi: SPIN_WHEEL_ABI,
|
|
240
173
|
functionName: "entryModule"
|
|
241
|
-
}),
|
|
242
|
-
basePublicClient.readContract({
|
|
243
|
-
address: spinwheelContractAddress as `0x${string}`,
|
|
244
|
-
abi: SPIN_WHEEL_ABI,
|
|
245
|
-
functionName: "getWheelInfo"
|
|
246
174
|
})
|
|
247
175
|
]);
|
|
248
176
|
|
|
@@ -253,17 +181,13 @@ export function AnySpendBuySpin({
|
|
|
253
181
|
entryModule: entryModuleAddress
|
|
254
182
|
};
|
|
255
183
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
state_: wheelInfo[5]
|
|
263
|
-
};
|
|
264
|
-
|
|
184
|
+
console.log("@@anyspend-buy-spin:config-fetched:", {
|
|
185
|
+
pricePerEntry: paymentConfig.pricePerEntry.toString(),
|
|
186
|
+
maxEntriesPerUser: paymentConfig.maxEntriesPerUser.toString(),
|
|
187
|
+
paymentRecipient: paymentConfig.paymentRecipient,
|
|
188
|
+
entryModule: paymentConfig.entryModule
|
|
189
|
+
});
|
|
265
190
|
setPaymentConfig(paymentConfig);
|
|
266
|
-
setWheelInfo(wheelInfoData);
|
|
267
191
|
} catch (error) {
|
|
268
192
|
console.error("@@anyspend-buy-spin:config-error:", error);
|
|
269
193
|
setConfigError("Failed to load spin wheel configuration");
|
|
@@ -282,7 +206,6 @@ export function AnySpendBuySpin({
|
|
|
282
206
|
useEffect(() => {
|
|
283
207
|
const timer = setTimeout(() => {
|
|
284
208
|
setDebouncedQuantity(displayQuantity);
|
|
285
|
-
setDebouncedUserSpinQuantity(userSpinQuantity);
|
|
286
209
|
}, 500);
|
|
287
210
|
|
|
288
211
|
return () => clearTimeout(timer);
|
|
@@ -315,23 +238,13 @@ export function AnySpendBuySpin({
|
|
|
315
238
|
}
|
|
316
239
|
|
|
317
240
|
// Check maximum entries per user (0 means no limit)
|
|
318
|
-
if (paymentConfig && paymentConfig.maxEntriesPerUser >
|
|
241
|
+
if (paymentConfig && paymentConfig.maxEntriesPerUser > BigInt(0) && BigInt(numValue) > paymentConfig.maxEntriesPerUser) {
|
|
319
242
|
setIsQuantityValid(false);
|
|
320
243
|
setUserSpinQuantity("");
|
|
321
244
|
setValidationError(`Maximum ${paymentConfig.maxEntriesPerUser.toString()} spins allowed`);
|
|
322
245
|
return;
|
|
323
246
|
}
|
|
324
247
|
|
|
325
|
-
// Check if quantity exceeds remaining entries
|
|
326
|
-
if (wheelInfo && BigInt(numValue) > wheelInfo.totalPrizesAvailable_ - wheelInfo.prizesRequestedCount_) {
|
|
327
|
-
setIsQuantityValid(false);
|
|
328
|
-
setUserSpinQuantity("");
|
|
329
|
-
setValidationError(
|
|
330
|
-
`Only ${(wheelInfo.totalPrizesAvailable_ - wheelInfo.prizesRequestedCount_).toString()} spins remaining`
|
|
331
|
-
);
|
|
332
|
-
return;
|
|
333
|
-
}
|
|
334
|
-
|
|
335
248
|
setUserSpinQuantity(value);
|
|
336
249
|
setIsQuantityValid(true);
|
|
337
250
|
setValidationError("");
|
|
@@ -386,7 +299,7 @@ export function AnySpendBuySpin({
|
|
|
386
299
|
} catch (error) {
|
|
387
300
|
console.error("@@anyspend-buy-spin:error:", error);
|
|
388
301
|
toast.error("Spin purchase failed. Please try again.");
|
|
389
|
-
|
|
302
|
+
setShowSuccessModal(false);
|
|
390
303
|
} finally {
|
|
391
304
|
setIsBuying(false);
|
|
392
305
|
}
|
|
@@ -465,40 +378,6 @@ export function AnySpendBuySpin({
|
|
|
465
378
|
// Render quantity input prompt
|
|
466
379
|
if (showAmountPrompt) {
|
|
467
380
|
const pricePerEntry = formatUnits(paymentConfig.pricePerEntry, 18);
|
|
468
|
-
const remainingEntries = wheelInfo ? wheelInfo.totalPrizesAvailable_ - wheelInfo.prizesRequestedCount_ : 0n;
|
|
469
|
-
const wheelStatus = wheelInfo ? getWheelStatus(wheelInfo) : null;
|
|
470
|
-
const isSoldOut = wheelStatus === "sold_out";
|
|
471
|
-
const isActive = wheelStatus === "active";
|
|
472
|
-
|
|
473
|
-
const getStatusMessage = () => {
|
|
474
|
-
if (!wheelInfo) return null;
|
|
475
|
-
|
|
476
|
-
const formatDate = (timestamp: bigint) => {
|
|
477
|
-
return new Date(Number(timestamp) * 1000).toLocaleString();
|
|
478
|
-
};
|
|
479
|
-
|
|
480
|
-
switch (wheelStatus) {
|
|
481
|
-
case "not_started":
|
|
482
|
-
return {
|
|
483
|
-
title: "Spin Wheel Not Started",
|
|
484
|
-
message: `Starts at ${formatDate(wheelInfo.startTime_)}`
|
|
485
|
-
};
|
|
486
|
-
case "ended":
|
|
487
|
-
return {
|
|
488
|
-
title: "Spin Wheel Ended",
|
|
489
|
-
message: `Ended at ${formatDate(wheelInfo.endTime_)}`
|
|
490
|
-
};
|
|
491
|
-
case "sold_out":
|
|
492
|
-
return {
|
|
493
|
-
title: "All Spins Have Been Claimed",
|
|
494
|
-
message: "Stay tuned for the next spin wheel event!"
|
|
495
|
-
};
|
|
496
|
-
default:
|
|
497
|
-
return null;
|
|
498
|
-
}
|
|
499
|
-
};
|
|
500
|
-
|
|
501
|
-
const statusInfo = getStatusMessage();
|
|
502
381
|
|
|
503
382
|
return (
|
|
504
383
|
<StyleRoot>
|
|
@@ -512,7 +391,7 @@ export function AnySpendBuySpin({
|
|
|
512
391
|
filter: hasMounted ? "blur(0px)" : "blur(10px)"
|
|
513
392
|
}}
|
|
514
393
|
transition={{ duration: 0.3, delay: 0, ease: "easeInOut" }}
|
|
515
|
-
className=
|
|
394
|
+
className="mb-4 flex justify-center"
|
|
516
395
|
>
|
|
517
396
|
<img
|
|
518
397
|
alt="B3 Token"
|
|
@@ -534,33 +413,15 @@ export function AnySpendBuySpin({
|
|
|
534
413
|
transition={{ duration: 0.3, delay: 0.1, ease: "easeInOut" }}
|
|
535
414
|
className="text-center"
|
|
536
415
|
>
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
<div className="inline-flex items-center gap-2">
|
|
547
|
-
<div className="bg-as-brand/10 border-as-brand/10 inline-flex items-center rounded-full border px-3 py-1">
|
|
548
|
-
<p className="text-as-brand text-sm font-medium">{pricePerEntry} $B3 per spin</p>
|
|
549
|
-
</div>
|
|
550
|
-
<div className="bg-as-brand/10 border-as-brand/10 inline-flex items-center rounded-full border px-3 py-1">
|
|
551
|
-
<p className="text-as-brand text-sm font-medium">{remainingEntries.toString()} remaining</p>
|
|
552
|
-
</div>
|
|
553
|
-
</div>
|
|
554
|
-
)}
|
|
555
|
-
</>
|
|
556
|
-
) : (
|
|
557
|
-
statusInfo && (
|
|
558
|
-
<div className="text-center">
|
|
559
|
-
<p className="text-as-primary text-lg font-semibold">{statusInfo.title}</p>
|
|
560
|
-
<p className="text-as-primary/70 mt-2 text-sm">{statusInfo.message}</p>
|
|
561
|
-
</div>
|
|
562
|
-
)
|
|
563
|
-
)}
|
|
416
|
+
<h2 className="font-sf-rounded text-as-primary mb-2 text-2xl font-bold">
|
|
417
|
+
{(() => {
|
|
418
|
+
const hasEnoughBalance = b3RawBalance && totalCost <= b3RawBalance;
|
|
419
|
+
return hasEnoughBalance || !debouncedQuantity ? "Buy Spins" : `Swap & Buy Spins`;
|
|
420
|
+
})()}
|
|
421
|
+
</h2>
|
|
422
|
+
<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">
|
|
423
|
+
<p className="text-as-primary/80 text-sm">{pricePerEntry} $B3 per spin</p>
|
|
424
|
+
</div>
|
|
564
425
|
</motion.div>
|
|
565
426
|
</div>
|
|
566
427
|
|
|
@@ -574,77 +435,163 @@ export function AnySpendBuySpin({
|
|
|
574
435
|
transition={{ duration: 0.3, delay: 0.2, ease: "easeInOut" }}
|
|
575
436
|
className="bg-b3-react-background w-full p-6"
|
|
576
437
|
>
|
|
577
|
-
|
|
578
|
-
<div className="
|
|
579
|
-
<
|
|
580
|
-
|
|
581
|
-
<
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
</div>
|
|
438
|
+
<div className="space-y-4">
|
|
439
|
+
<div className="flex items-center justify-between">
|
|
440
|
+
<p className="text-as-primary/70 text-sm font-medium">Number of spins</p>
|
|
441
|
+
<span className="text-as-primary/50 flex items-center gap-1 text-sm">
|
|
442
|
+
Available: {isBalanceLoading ? <Loader2 className="h-3 w-3 animate-spin" /> : `${b3Balance} B3`}
|
|
443
|
+
</span>
|
|
444
|
+
</div>
|
|
585
445
|
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
</div>
|
|
446
|
+
<div className="relative">
|
|
447
|
+
<Input
|
|
448
|
+
onFocus={onFocusQuantityInput}
|
|
449
|
+
type="text"
|
|
450
|
+
placeholder="1"
|
|
451
|
+
value={displayQuantity}
|
|
452
|
+
onChange={e => validateAndSetQuantity(e.target.value)}
|
|
453
|
+
className={`h-14 px-4 pr-20 text-lg ${!isQuantityValid && displayQuantity ? "border-as-red" : "border-b3-react-border"}`}
|
|
454
|
+
/>
|
|
455
|
+
<div className="font-pack absolute right-4 top-1/2 -translate-y-1/2 text-lg font-medium text-blue-500/70">
|
|
456
|
+
{displayQuantity === "1" ? "Spin" : "Spins"}
|
|
598
457
|
</div>
|
|
458
|
+
</div>
|
|
599
459
|
|
|
600
|
-
|
|
460
|
+
{!isQuantityValid && displayQuantity && <p className="text-as-red text-sm">{validationError}</p>}
|
|
601
461
|
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
</div>
|
|
462
|
+
<div className="bg-as-on-surface-2/30 rounded-lg border border-white/10 p-4 backdrop-blur-sm">
|
|
463
|
+
<div className="flex items-center justify-between">
|
|
464
|
+
<span className="text-as-primary/70 text-sm font-medium">Total Cost:</span>
|
|
465
|
+
<div className="flex items-center gap-2">
|
|
466
|
+
<span className="text-as-primary text-lg font-bold">
|
|
467
|
+
{displayQuantity && isQuantityValid ? formatUnits(totalCost, 18) : "0"} B3
|
|
468
|
+
</span>
|
|
610
469
|
</div>
|
|
611
470
|
</div>
|
|
471
|
+
</div>
|
|
472
|
+
</div>
|
|
473
|
+
|
|
474
|
+
<div className="mt-4">
|
|
475
|
+
{(() => {
|
|
476
|
+
const hasEnoughBalance = b3RawBalance && totalCost <= b3RawBalance;
|
|
477
|
+
|
|
478
|
+
if (!hasEnoughBalance && debouncedQuantity) {
|
|
479
|
+
return (
|
|
480
|
+
<div className="bg-as-brand/10 flex flex-col items-center gap-2 rounded-lg p-4 pb-5">
|
|
481
|
+
<div className="flex items-center justify-center gap-2">
|
|
482
|
+
<span className="text-as-primary text-sm font-semibold">Swap & buy from any token</span>
|
|
483
|
+
<TextLoop>
|
|
484
|
+
<EthIcon className="h-8 w-8" />
|
|
485
|
+
<SolIcon className="h-8 w-8" />
|
|
486
|
+
<UsdcIcon className="h-8 w-8" />
|
|
487
|
+
</TextLoop>
|
|
488
|
+
<ArrowRight className="text-as-primary h-4 w-4" />
|
|
489
|
+
<img src="https://cdn.b3.fun/b3-coin-3d.png" className="h-7 w-7" alt="B3 Token" />
|
|
490
|
+
</div>
|
|
491
|
+
<p className="text-as-primary/50 text-sm font-medium">
|
|
492
|
+
No problem, we'll help you swap to B3 for your spins!
|
|
493
|
+
</p>
|
|
494
|
+
</div>
|
|
495
|
+
);
|
|
496
|
+
}
|
|
497
|
+
})()}
|
|
498
|
+
</div>
|
|
499
|
+
|
|
500
|
+
<Button
|
|
501
|
+
onClick={confirmQuantity}
|
|
502
|
+
disabled={!isQuantityValid || !displayQuantity || isBuying || isTxPending}
|
|
503
|
+
className="bg-as-brand hover:bg-as-brand/90 text-as-primary mt-4 h-14 w-full rounded-xl text-lg font-medium"
|
|
504
|
+
>
|
|
505
|
+
{isBuying ? "Buying..." : isTxPending ? "Confirming..." : "Continue"}
|
|
506
|
+
</Button>
|
|
507
|
+
</motion.div>
|
|
508
|
+
</div>
|
|
509
|
+
</StyleRoot>
|
|
510
|
+
);
|
|
511
|
+
}
|
|
612
512
|
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
513
|
+
// Success Modal for Direct Buying
|
|
514
|
+
if (showSuccessModal) {
|
|
515
|
+
return (
|
|
516
|
+
<StyleRoot>
|
|
517
|
+
<div className="bg-b3-react-background flex w-full flex-col items-center">
|
|
518
|
+
<div className="w-full p-4">
|
|
519
|
+
<motion.div
|
|
520
|
+
initial={false}
|
|
521
|
+
animate={{
|
|
522
|
+
opacity: hasMounted ? 1 : 0,
|
|
523
|
+
y: hasMounted ? 0 : 20,
|
|
524
|
+
filter: hasMounted ? "blur(0px)" : "blur(10px)"
|
|
525
|
+
}}
|
|
526
|
+
transition={{ duration: 0.3, delay: 0, ease: "easeInOut" }}
|
|
527
|
+
className="relative mx-auto mb-4 size-[120px]"
|
|
528
|
+
>
|
|
529
|
+
<div className="absolute inset-0 scale-95 rounded-[50%] bg-gradient-to-br from-green-500/30 to-blue-500/30 blur-xl"></div>
|
|
530
|
+
<GlareCardRounded className="overflow-hidden rounded-full border-none bg-gradient-to-br from-green-500/10 to-blue-500/10 backdrop-blur-sm">
|
|
531
|
+
<img
|
|
532
|
+
alt="B3 Token"
|
|
533
|
+
loading="lazy"
|
|
534
|
+
width="120"
|
|
535
|
+
height="120"
|
|
536
|
+
decoding="async"
|
|
537
|
+
data-nimg="1"
|
|
538
|
+
className="size-full shrink-0 bg-transparent text-transparent"
|
|
539
|
+
src="https://cdn.b3.fun/b3-coin-3d.png"
|
|
540
|
+
/>
|
|
541
|
+
<div className="absolute inset-0 rounded-[50%] border border-white/20"></div>
|
|
542
|
+
</GlareCardRounded>
|
|
543
|
+
</motion.div>
|
|
544
|
+
<motion.div
|
|
545
|
+
initial={false}
|
|
546
|
+
animate={{
|
|
547
|
+
opacity: hasMounted ? 1 : 0,
|
|
548
|
+
y: hasMounted ? 0 : 20,
|
|
549
|
+
filter: hasMounted ? "blur(0px)" : "blur(10px)"
|
|
550
|
+
}}
|
|
551
|
+
transition={{ duration: 0.3, delay: 0.1, ease: "easeInOut" }}
|
|
552
|
+
className="text-center"
|
|
553
|
+
>
|
|
554
|
+
<h2 className="font-sf-rounded mb-3 bg-gradient-to-r from-green-400 to-blue-500 bg-clip-text text-3xl font-bold text-transparent">
|
|
555
|
+
🎉 Purchase Complete!
|
|
556
|
+
</h2>
|
|
557
|
+
<div className="bg-as-on-surface-2/50 inline-flex items-center gap-2 rounded-full border border-white/10 px-4 py-2 backdrop-blur-sm">
|
|
558
|
+
<span className="text-as-primary/80 text-sm font-medium">
|
|
559
|
+
{userSpinQuantity} Spin{userSpinQuantity !== "1" ? "s" : ""} • {formatUnits(totalCost, 18)} B3
|
|
560
|
+
</span>
|
|
646
561
|
</div>
|
|
647
|
-
|
|
562
|
+
</motion.div>
|
|
563
|
+
</div>
|
|
564
|
+
|
|
565
|
+
<motion.div
|
|
566
|
+
initial={false}
|
|
567
|
+
animate={{
|
|
568
|
+
opacity: hasMounted ? 1 : 0,
|
|
569
|
+
y: hasMounted ? 0 : 20,
|
|
570
|
+
filter: hasMounted ? "blur(0px)" : "blur(10px)"
|
|
571
|
+
}}
|
|
572
|
+
transition={{ duration: 0.3, delay: 0.2, ease: "easeInOut" }}
|
|
573
|
+
className="bg-b3-react-background w-full p-6"
|
|
574
|
+
>
|
|
575
|
+
<div className="mb-6">
|
|
576
|
+
<a
|
|
577
|
+
href={`https://basescan.org/tx/${buyingTxHash}`}
|
|
578
|
+
target="_blank"
|
|
579
|
+
rel="noopener noreferrer"
|
|
580
|
+
className="text-as-primary/70 hover:text-as-primary block break-all text-center font-mono text-sm underline transition-colors"
|
|
581
|
+
>
|
|
582
|
+
View transaction
|
|
583
|
+
</a>
|
|
584
|
+
</div>
|
|
585
|
+
|
|
586
|
+
<Button
|
|
587
|
+
onClick={() => {
|
|
588
|
+
setB3ModalOpen(false);
|
|
589
|
+
onSuccess?.(buyingTxHash);
|
|
590
|
+
}}
|
|
591
|
+
className="bg-as-brand hover:bg-as-brand/90 text-as-primary h-14 w-full rounded-xl text-lg font-medium"
|
|
592
|
+
>
|
|
593
|
+
Done
|
|
594
|
+
</Button>
|
|
648
595
|
</motion.div>
|
|
649
596
|
</div>
|
|
650
597
|
</StyleRoot>
|
|
@@ -311,9 +311,6 @@ export function getPaymentUrl(address: string, amount: bigint, currency: string)
|
|
|
311
311
|
}
|
|
312
312
|
|
|
313
313
|
export function getExplorerTxUrl(chainId: number, txHash: string) {
|
|
314
|
-
if (chainId === b3.id) {
|
|
315
|
-
return "https://explorer.b3.fun/b3/tx/" + txHash;
|
|
316
|
-
}
|
|
317
314
|
if (EVM_CHAINS[chainId]) {
|
|
318
315
|
return EVM_CHAINS[chainId].viem.blockExplorers?.default.url + "/tx/" + txHash;
|
|
319
316
|
}
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
} from "@b3dotfun/sdk/anyspend/react";
|
|
9
9
|
import { useIsMobile, useModalStore } from "@b3dotfun/sdk/global-account/react";
|
|
10
10
|
import { debugB3React } from "@b3dotfun/sdk/shared/utils/debug";
|
|
11
|
-
import { useB3 } from "./B3Provider
|
|
11
|
+
import { useB3 } from "./B3Provider";
|
|
12
12
|
import { ManageAccount } from "./ManageAccount/ManageAccount";
|
|
13
13
|
import { RequestPermissions } from "./RequestPermissions/RequestPermissions";
|
|
14
14
|
import { SignInWithB3Flow } from "./SignInWithB3/SignInWithB3Flow";
|
|
@@ -6,7 +6,6 @@ import { Account } from "thirdweb/wallets";
|
|
|
6
6
|
// import { RelayKitProviderWrapper } from "./RelayKitProviderWrapper";
|
|
7
7
|
|
|
8
8
|
import { User } from "@b3dotfun/sdk/global-account/types/b3-api.types";
|
|
9
|
-
import { B3Context, B3ContextType } from "./types";
|
|
10
9
|
|
|
11
10
|
/**
|
|
12
11
|
* Default permissions configuration for B3 provider
|
|
@@ -18,6 +17,51 @@ const DEFAULT_PERMISSIONS = {
|
|
|
18
17
|
endDate: new Date(Date.now() + 1000 * 60 * 60 * 24 * 365) // 1 year from now
|
|
19
18
|
};
|
|
20
19
|
|
|
20
|
+
/**
|
|
21
|
+
* Context type for B3Provider
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
export interface B3ContextType {
|
|
25
|
+
account?: Account;
|
|
26
|
+
user?: User;
|
|
27
|
+
setAccount: (account: Account) => void;
|
|
28
|
+
setUser: (user?: User) => void;
|
|
29
|
+
initialized: boolean;
|
|
30
|
+
ready: boolean;
|
|
31
|
+
environment?: "development" | "production";
|
|
32
|
+
defaultPermissions?: PermissionsConfig;
|
|
33
|
+
theme: "light" | "dark";
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Context for B3 provider
|
|
38
|
+
*/
|
|
39
|
+
export const B3Context = createContext<B3ContextType>({
|
|
40
|
+
account: undefined,
|
|
41
|
+
user: undefined,
|
|
42
|
+
setAccount: () => {},
|
|
43
|
+
setUser: () => {},
|
|
44
|
+
initialized: false,
|
|
45
|
+
ready: false,
|
|
46
|
+
environment: "development",
|
|
47
|
+
theme: "light"
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Hook to access the B3 context
|
|
52
|
+
* @throws Error if used outside a B3Provider
|
|
53
|
+
*/
|
|
54
|
+
export function useB3() {
|
|
55
|
+
const context = useContext(B3Context);
|
|
56
|
+
|
|
57
|
+
if (!context.initialized) {
|
|
58
|
+
throw new Error("useB3 must be used within a B3Provider");
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Return a stable reference
|
|
62
|
+
return useMemo(() => context, [context]);
|
|
63
|
+
}
|
|
64
|
+
|
|
21
65
|
// Create queryClient instance
|
|
22
66
|
const queryClient = new QueryClient();
|
|
23
67
|
|
|
@@ -81,9 +125,6 @@ export function InnerProvider({
|
|
|
81
125
|
<B3Context.Provider
|
|
82
126
|
value={{
|
|
83
127
|
account: effectiveAccount,
|
|
84
|
-
automaticallySetFirstEoa: false,
|
|
85
|
-
setWallet: () => {},
|
|
86
|
-
wallet: undefined,
|
|
87
128
|
setAccount,
|
|
88
129
|
user,
|
|
89
130
|
setUser,
|