@dubsdotapp/expo 0.3.3 → 0.3.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/index.mjs CHANGED
@@ -529,6 +529,20 @@ var DubsClient = class {
529
529
  );
530
530
  return { pool: res.pool, stats: res.stats };
531
531
  }
532
+ /** Build unsigned entry transaction for an arcade pool */
533
+ async buildArcadeEntry(poolId, walletAddress) {
534
+ const res = await this.request(
535
+ "POST",
536
+ `/arcade/pools/${poolId}/build-enter`,
537
+ { walletAddress }
538
+ );
539
+ return {
540
+ transaction: res.transaction,
541
+ poolId: res.poolId,
542
+ amount: res.amount,
543
+ destination: res.destination
544
+ };
545
+ }
532
546
  async enterArcadePool(poolId, params) {
533
547
  const res = await this.request(
534
548
  "POST",
@@ -622,7 +636,7 @@ function createSecureStoreStorage() {
622
636
  }
623
637
 
624
638
  // src/provider.tsx
625
- import { createContext as createContext4, useContext as useContext4, useMemo as useMemo3, useCallback as useCallback18, useState as useState19, useEffect as useEffect13 } from "react";
639
+ import { createContext as createContext4, useContext as useContext4, useMemo as useMemo3, useCallback as useCallback19, useState as useState20, useEffect as useEffect13 } from "react";
626
640
 
627
641
  // src/ui/theme.ts
628
642
  import { createContext, useContext } from "react";
@@ -1687,7 +1701,7 @@ function ManagedWalletProvider({
1687
1701
  }
1688
1702
 
1689
1703
  // src/ui/AuthGate.tsx
1690
- import React2, { useState as useState18, useEffect as useEffect12, useRef as useRef4, useCallback as useCallback17 } from "react";
1704
+ import React2, { useState as useState19, useEffect as useEffect12, useRef as useRef4, useCallback as useCallback18 } from "react";
1691
1705
  import {
1692
1706
  View as View3,
1693
1707
  Text as Text3,
@@ -2664,6 +2678,64 @@ function useArcadeGame(poolId, maxLives = 3) {
2664
2678
  };
2665
2679
  }
2666
2680
 
2681
+ // src/hooks/useEnterArcadePool.ts
2682
+ import { useState as useState18, useCallback as useCallback17 } from "react";
2683
+ function useEnterArcadePool() {
2684
+ const { client, wallet, connection } = useDubs();
2685
+ const { user } = useAuth();
2686
+ const [status, setStatus] = useState18("idle");
2687
+ const [error, setError] = useState18(null);
2688
+ const [data, setData] = useState18(null);
2689
+ const reset = useCallback17(() => {
2690
+ setStatus("idle");
2691
+ setError(null);
2692
+ setData(null);
2693
+ }, []);
2694
+ const execute = useCallback17(async (poolId) => {
2695
+ if (!wallet.publicKey) throw new Error("Wallet not connected");
2696
+ const walletAddress = wallet.publicKey.toBase58();
2697
+ setStatus("building");
2698
+ setError(null);
2699
+ setData(null);
2700
+ try {
2701
+ console.log("[useEnterArcadePool] Step 1: Building transaction...", { poolId, walletAddress });
2702
+ const buildResult = await client.buildArcadeEntry(poolId, walletAddress);
2703
+ console.log("[useEnterArcadePool] Step 1 done:", { poolId: buildResult.poolId, amount: buildResult.amount });
2704
+ setStatus("signing");
2705
+ console.log("[useEnterArcadePool] Step 2: Signing and sending...");
2706
+ const signature = await signAndSendBase64Transaction(
2707
+ buildResult.transaction,
2708
+ wallet,
2709
+ connection
2710
+ );
2711
+ console.log("[useEnterArcadePool] Step 2 done. Signature:", signature);
2712
+ setStatus("confirming");
2713
+ console.log("[useEnterArcadePool] Step 3: Confirming with backend...");
2714
+ const entry = await client.enterArcadePool(poolId, {
2715
+ walletAddress,
2716
+ txSignature: signature
2717
+ });
2718
+ console.log("[useEnterArcadePool] Step 3 done. Entry recorded.");
2719
+ const result = {
2720
+ poolId,
2721
+ signature,
2722
+ entry
2723
+ };
2724
+ setData(result);
2725
+ setStatus("success");
2726
+ console.log("[useEnterArcadePool] Complete!");
2727
+ return result;
2728
+ } catch (err) {
2729
+ console.error("[useEnterArcadePool] FAILED at status:", status, err);
2730
+ const e = err instanceof Error ? err : new Error(String(err));
2731
+ setError(e);
2732
+ setStatus("error");
2733
+ throw e;
2734
+ }
2735
+ }, [client, wallet, connection]);
2736
+ return { execute, status, error, data, reset };
2737
+ }
2738
+
2667
2739
  // src/ui/AvatarEditor.tsx
2668
2740
  import {
2669
2741
  View as View2,
@@ -2831,10 +2903,10 @@ function AuthGate({
2831
2903
  }) {
2832
2904
  const { client, pushEnabled } = useDubs();
2833
2905
  const auth = useAuth();
2834
- const [phase, setPhase] = useState18("init");
2835
- const [registrationPhase, setRegistrationPhase] = useState18(false);
2836
- const [showPushSetup, setShowPushSetup] = useState18(false);
2837
- const [isRestoredSession, setIsRestoredSession] = useState18(false);
2906
+ const [phase, setPhase] = useState19("init");
2907
+ const [registrationPhase, setRegistrationPhase] = useState19(false);
2908
+ const [showPushSetup, setShowPushSetup] = useState19(false);
2909
+ const [isRestoredSession, setIsRestoredSession] = useState19(false);
2838
2910
  useEffect12(() => {
2839
2911
  let cancelled = false;
2840
2912
  (async () => {
@@ -2873,12 +2945,12 @@ function AuthGate({
2873
2945
  useEffect12(() => {
2874
2946
  if (auth.token) onSaveToken(auth.token);
2875
2947
  }, [auth.token]);
2876
- const retry = useCallback17(() => {
2948
+ const retry = useCallback18(() => {
2877
2949
  setRegistrationPhase(false);
2878
2950
  auth.reset();
2879
2951
  auth.authenticate();
2880
2952
  }, [auth]);
2881
- const handleRegister = useCallback17(
2953
+ const handleRegister = useCallback18(
2882
2954
  (username, referralCode, avatarUrl) => {
2883
2955
  auth.register(username, referralCode, avatarUrl);
2884
2956
  },
@@ -2994,15 +3066,15 @@ function DefaultRegistrationScreen({
2994
3066
  }) {
2995
3067
  const t = useDubsTheme();
2996
3068
  const accent = accentColor || t.accent;
2997
- const [step, setStep] = useState18(0);
2998
- const [avatarSeed, setAvatarSeed] = useState18(generateSeed);
2999
- const [avatarStyle, setAvatarStyle] = useState18("adventurer");
3000
- const [avatarBg, setAvatarBg] = useState18("1a1a2e");
3001
- const [showStyles, setShowStyles] = useState18(false);
3002
- const [username, setUsername] = useState18("");
3003
- const [referralCode, setReferralCode] = useState18("");
3004
- const [checking, setChecking] = useState18(false);
3005
- const [availability, setAvailability] = useState18(null);
3069
+ const [step, setStep] = useState19(0);
3070
+ const [avatarSeed, setAvatarSeed] = useState19(generateSeed);
3071
+ const [avatarStyle, setAvatarStyle] = useState19("adventurer");
3072
+ const [avatarBg, setAvatarBg] = useState19("1a1a2e");
3073
+ const [showStyles, setShowStyles] = useState19(false);
3074
+ const [username, setUsername] = useState19("");
3075
+ const [referralCode, setReferralCode] = useState19("");
3076
+ const [checking, setChecking] = useState19(false);
3077
+ const [availability, setAvailability] = useState19(null);
3006
3078
  const debounceRef = useRef4(null);
3007
3079
  const fadeAnim = useRef4(new Animated.Value(1)).current;
3008
3080
  const slideAnim = useRef4(new Animated.Value(0)).current;
@@ -3030,7 +3102,7 @@ function DefaultRegistrationScreen({
3030
3102
  if (debounceRef.current) clearTimeout(debounceRef.current);
3031
3103
  };
3032
3104
  }, [username, client]);
3033
- const animateToStep = useCallback17((newStep) => {
3105
+ const animateToStep = useCallback18((newStep) => {
3034
3106
  const dir = newStep > step ? 1 : -1;
3035
3107
  Keyboard.dismiss();
3036
3108
  Animated.parallel([
@@ -3447,8 +3519,8 @@ function DubsProvider({
3447
3519
  const rpcUrl = rpcUrlOverride || config.rpcUrl;
3448
3520
  const client = useMemo3(() => new DubsClient({ apiKey, baseUrl }), [apiKey, baseUrl]);
3449
3521
  const storage = useMemo3(() => tokenStorage || createSecureStoreStorage(), [tokenStorage]);
3450
- const [uiConfig, setUiConfig] = useState19(null);
3451
- const [resolvedNetwork, setResolvedNetwork] = useState19(network);
3522
+ const [uiConfig, setUiConfig] = useState20(null);
3523
+ const [resolvedNetwork, setResolvedNetwork] = useState20(network);
3452
3524
  useEffect13(() => {
3453
3525
  client.getAppConfig().then((cfg) => {
3454
3526
  console.log("[DubsProvider] UI config loaded:", JSON.stringify(cfg));
@@ -3541,7 +3613,7 @@ function ManagedInner({
3541
3613
  children
3542
3614
  }) {
3543
3615
  const managedDisconnect = useDisconnect();
3544
- const disconnect = useCallback18(async () => {
3616
+ const disconnect = useCallback19(async () => {
3545
3617
  client.setToken(null);
3546
3618
  await managedDisconnect?.();
3547
3619
  }, [client, managedDisconnect]);
@@ -3582,7 +3654,7 @@ function ExternalWalletProvider({
3582
3654
  pushEnabled,
3583
3655
  children
3584
3656
  }) {
3585
- const disconnect = useCallback18(async () => {
3657
+ const disconnect = useCallback19(async () => {
3586
3658
  client.setToken(null);
3587
3659
  await storage.deleteItem(STORAGE_KEYS.JWT_TOKEN).catch(() => {
3588
3660
  });
@@ -3845,7 +3917,7 @@ var styles4 = StyleSheet5.create({
3845
3917
  });
3846
3918
 
3847
3919
  // src/ui/UserProfileSheet.tsx
3848
- import { useState as useState20, useEffect as useEffect14, useRef as useRef5, useCallback as useCallback19, useMemo as useMemo5 } from "react";
3920
+ import { useState as useState21, useEffect as useEffect14, useRef as useRef5, useCallback as useCallback20, useMemo as useMemo5 } from "react";
3849
3921
  import {
3850
3922
  View as View6,
3851
3923
  Text as Text6,
@@ -3878,11 +3950,11 @@ function UserProfileSheet({
3878
3950
  const push = usePushNotifications();
3879
3951
  const overlayOpacity = useRef5(new Animated2.Value(0)).current;
3880
3952
  const parsed = useMemo5(() => parseAvatarUrl(user.avatar), [user.avatar]);
3881
- const [avatarStyle, setAvatarStyle] = useState20(parsed.style);
3882
- const [avatarSeed, setAvatarSeed] = useState20(parsed.seed);
3883
- const [bgColor, setBgColor] = useState20(parsed.bg);
3884
- const [saving, setSaving] = useState20(false);
3885
- const [error, setError] = useState20(null);
3953
+ const [avatarStyle, setAvatarStyle] = useState21(parsed.style);
3954
+ const [avatarSeed, setAvatarSeed] = useState21(parsed.seed);
3955
+ const [bgColor, setBgColor] = useState21(parsed.bg);
3956
+ const [saving, setSaving] = useState21(false);
3957
+ const [error, setError] = useState21(null);
3886
3958
  useEffect14(() => {
3887
3959
  const p = parseAvatarUrl(user.avatar);
3888
3960
  setAvatarStyle(p.style);
@@ -3900,7 +3972,7 @@ function UserProfileSheet({
3900
3972
  if (visible) setError(null);
3901
3973
  }, [visible]);
3902
3974
  const currentAvatarUrl = getAvatarUrl(avatarStyle, avatarSeed, bgColor);
3903
- const saveAvatar = useCallback19(async (newUrl) => {
3975
+ const saveAvatar = useCallback20(async (newUrl) => {
3904
3976
  setSaving(true);
3905
3977
  setError(null);
3906
3978
  try {
@@ -3913,16 +3985,16 @@ function UserProfileSheet({
3913
3985
  setSaving(false);
3914
3986
  }
3915
3987
  }, [client, refreshUser, onAvatarUpdated]);
3916
- const handleStyleChange = useCallback19((style) => {
3988
+ const handleStyleChange = useCallback20((style) => {
3917
3989
  setAvatarStyle(style);
3918
3990
  saveAvatar(getAvatarUrl(style, avatarSeed, bgColor));
3919
3991
  }, [avatarSeed, bgColor, saveAvatar]);
3920
- const handleShuffle = useCallback19(() => {
3992
+ const handleShuffle = useCallback20(() => {
3921
3993
  const newSeed = generateSeed();
3922
3994
  setAvatarSeed(newSeed);
3923
3995
  saveAvatar(getAvatarUrl(avatarStyle, newSeed, bgColor));
3924
3996
  }, [avatarStyle, bgColor, saveAvatar]);
3925
- const handleBgChange = useCallback19((color) => {
3997
+ const handleBgChange = useCallback20((color) => {
3926
3998
  setBgColor(color);
3927
3999
  saveAvatar(getAvatarUrl(avatarStyle, avatarSeed, color));
3928
4000
  }, [avatarStyle, avatarSeed, saveAvatar]);
@@ -4202,7 +4274,7 @@ var styles5 = StyleSheet6.create({
4202
4274
  });
4203
4275
 
4204
4276
  // src/ui/game/GamePoster.tsx
4205
- import { useState as useState21 } from "react";
4277
+ import { useState as useState22 } from "react";
4206
4278
  import { StyleSheet as StyleSheet7, View as View7, Text as Text7 } from "react-native";
4207
4279
  import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
4208
4280
  function computeCountdown(lockTimestamp) {
@@ -4252,7 +4324,7 @@ function GamePoster({ game, ImageComponent }) {
4252
4324
  ] });
4253
4325
  }
4254
4326
  function TeamLogoInternal({ url, size, Img }) {
4255
- const [failed, setFailed] = useState21(false);
4327
+ const [failed, setFailed] = useState22(false);
4256
4328
  if (!url || failed) {
4257
4329
  return /* @__PURE__ */ jsx9(View7, { style: [styles6.logoPlaceholder, { width: size, height: size, borderRadius: size / 2 }] });
4258
4330
  }
@@ -4432,7 +4504,7 @@ var styles7 = StyleSheet8.create({
4432
4504
  });
4433
4505
 
4434
4506
  // src/ui/game/PickWinnerCard.tsx
4435
- import { useState as useState22, useMemo as useMemo7 } from "react";
4507
+ import { useState as useState23, useMemo as useMemo7 } from "react";
4436
4508
  import { StyleSheet as StyleSheet9, View as View9, Text as Text9, TouchableOpacity as TouchableOpacity6 } from "react-native";
4437
4509
  import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
4438
4510
  function PickWinnerCard({
@@ -4503,7 +4575,7 @@ function TeamOption({
4503
4575
  ImageComponent,
4504
4576
  t
4505
4577
  }) {
4506
- const [imgFailed, setImgFailed] = useState22(false);
4578
+ const [imgFailed, setImgFailed] = useState23(false);
4507
4579
  const Img = ImageComponent || __require("react-native").Image;
4508
4580
  const showImage = imageUrl && !imgFailed;
4509
4581
  return /* @__PURE__ */ jsxs9(
@@ -4544,7 +4616,7 @@ var styles8 = StyleSheet9.create({
4544
4616
  });
4545
4617
 
4546
4618
  // src/ui/game/PlayersCard.tsx
4547
- import { useState as useState23 } from "react";
4619
+ import { useState as useState24 } from "react";
4548
4620
  import { StyleSheet as StyleSheet10, View as View10, Text as Text10 } from "react-native";
4549
4621
  import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
4550
4622
  function truncateWallet(addr, chars) {
@@ -4593,7 +4665,7 @@ function BettorRow({
4593
4665
  ImageComponent,
4594
4666
  t
4595
4667
  }) {
4596
- const [imgFailed, setImgFailed] = useState23(false);
4668
+ const [imgFailed, setImgFailed] = useState24(false);
4597
4669
  const Img = ImageComponent || __require("react-native").Image;
4598
4670
  const showAvatar = bettor.avatar && !imgFailed;
4599
4671
  return /* @__PURE__ */ jsxs10(View10, { style: [styles9.row, !isFirst && { borderTopColor: t.border, borderTopWidth: 1 }], children: [
@@ -4672,7 +4744,7 @@ var styles10 = StyleSheet11.create({
4672
4744
  });
4673
4745
 
4674
4746
  // src/ui/game/CreateCustomGameSheet.tsx
4675
- import { useState as useState24, useEffect as useEffect15, useRef as useRef6, useCallback as useCallback20 } from "react";
4747
+ import { useState as useState25, useEffect as useEffect15, useRef as useRef6, useCallback as useCallback21 } from "react";
4676
4748
  import {
4677
4749
  View as View12,
4678
4750
  Text as Text12,
@@ -4709,9 +4781,9 @@ function CreateCustomGameSheet({
4709
4781
  const t = useDubsTheme();
4710
4782
  const { wallet } = useDubs();
4711
4783
  const mutation = useCreateCustomGame();
4712
- const [selectedAmount, setSelectedAmount] = useState24(null);
4713
- const [customAmount, setCustomAmount] = useState24("");
4714
- const [isCustom, setIsCustom] = useState24(false);
4784
+ const [selectedAmount, setSelectedAmount] = useState25(null);
4785
+ const [customAmount, setCustomAmount] = useState25("");
4786
+ const [isCustom, setIsCustom] = useState25(false);
4715
4787
  const overlayOpacity = useRef6(new Animated3.Value(0)).current;
4716
4788
  useEffect15(() => {
4717
4789
  Animated3.timing(overlayOpacity, {
@@ -4742,18 +4814,18 @@ function CreateCustomGameSheet({
4742
4814
  onError?.(mutation.error);
4743
4815
  }
4744
4816
  }, [mutation.status, mutation.error]);
4745
- const handlePresetSelect = useCallback20((amount) => {
4817
+ const handlePresetSelect = useCallback21((amount) => {
4746
4818
  setSelectedAmount(amount);
4747
4819
  setIsCustom(false);
4748
4820
  setCustomAmount("");
4749
4821
  onAmountChange?.(amount);
4750
4822
  }, [onAmountChange]);
4751
- const handleCustomSelect = useCallback20(() => {
4823
+ const handleCustomSelect = useCallback21(() => {
4752
4824
  setIsCustom(true);
4753
4825
  setSelectedAmount(null);
4754
4826
  onAmountChange?.(null);
4755
4827
  }, [onAmountChange]);
4756
- const handleCustomAmountChange = useCallback20((text) => {
4828
+ const handleCustomAmountChange = useCallback21((text) => {
4757
4829
  const cleaned = text.replace(/[^0-9.]/g, "").replace(/(\..*?)\..*/g, "$1");
4758
4830
  setCustomAmount(cleaned);
4759
4831
  const parsed = parseFloat(cleaned);
@@ -4768,7 +4840,7 @@ function CreateCustomGameSheet({
4768
4840
  const winnerTakes = pot * (1 - fee / 100);
4769
4841
  const isMutating = mutation.status !== "idle" && mutation.status !== "success" && mutation.status !== "error";
4770
4842
  const canCreate = finalAmount !== null && finalAmount > 0 && !isMutating && mutation.status !== "success";
4771
- const handleCreate = useCallback20(async () => {
4843
+ const handleCreate = useCallback21(async () => {
4772
4844
  if (!finalAmount || !wallet.publicKey) return;
4773
4845
  try {
4774
4846
  await mutation.execute({
@@ -5037,7 +5109,7 @@ var styles11 = StyleSheet12.create({
5037
5109
  });
5038
5110
 
5039
5111
  // src/ui/game/JoinGameSheet.tsx
5040
- import { useState as useState25, useEffect as useEffect16, useRef as useRef7, useCallback as useCallback21, useMemo as useMemo9 } from "react";
5112
+ import { useState as useState26, useEffect as useEffect16, useRef as useRef7, useCallback as useCallback22, useMemo as useMemo9 } from "react";
5041
5113
  import {
5042
5114
  View as View13,
5043
5115
  Text as Text13,
@@ -5073,7 +5145,7 @@ function JoinGameSheet({
5073
5145
  const { wallet } = useDubs();
5074
5146
  const mutation = useJoinGame();
5075
5147
  const isCustomGame = game.gameMode === CUSTOM_GAME_MODE;
5076
- const [selectedTeam, setSelectedTeam] = useState25(null);
5148
+ const [selectedTeam, setSelectedTeam] = useState26(null);
5077
5149
  const overlayOpacity = useRef7(new Animated4.Value(0)).current;
5078
5150
  useEffect16(() => {
5079
5151
  Animated4.timing(overlayOpacity, {
@@ -5127,7 +5199,7 @@ function JoinGameSheet({
5127
5199
  }, [bettors, wallet.publicKey]);
5128
5200
  const isMutating = mutation.status !== "idle" && mutation.status !== "success" && mutation.status !== "error";
5129
5201
  const canJoin = selectedTeam !== null && !isMutating && mutation.status !== "success" && !alreadyJoined;
5130
- const handleJoin = useCallback21(async () => {
5202
+ const handleJoin = useCallback22(async () => {
5131
5203
  if (!selectedTeam || !wallet.publicKey) return;
5132
5204
  try {
5133
5205
  await mutation.execute({
@@ -5271,7 +5343,7 @@ function TeamButton({
5271
5343
  ImageComponent,
5272
5344
  t
5273
5345
  }) {
5274
- const [imgFailed, setImgFailed] = useState25(false);
5346
+ const [imgFailed, setImgFailed] = useState26(false);
5275
5347
  const Img = ImageComponent || __require("react-native").Image;
5276
5348
  const showImage = imageUrl && !imgFailed;
5277
5349
  return /* @__PURE__ */ jsxs13(
@@ -5448,7 +5520,7 @@ var styles12 = StyleSheet13.create({
5448
5520
  });
5449
5521
 
5450
5522
  // src/ui/game/ClaimPrizeSheet.tsx
5451
- import { useState as useState26, useEffect as useEffect17, useRef as useRef8, useCallback as useCallback22 } from "react";
5523
+ import { useState as useState27, useEffect as useEffect17, useRef as useRef8, useCallback as useCallback23 } from "react";
5452
5524
  import {
5453
5525
  View as View14,
5454
5526
  Text as Text14,
@@ -5482,7 +5554,7 @@ function ClaimPrizeSheet({
5482
5554
  const overlayOpacity = useRef8(new Animated5.Value(0)).current;
5483
5555
  const celebrationScale = useRef8(new Animated5.Value(0)).current;
5484
5556
  const celebrationOpacity = useRef8(new Animated5.Value(0)).current;
5485
- const [showCelebration, setShowCelebration] = useState26(false);
5557
+ const [showCelebration, setShowCelebration] = useState27(false);
5486
5558
  useEffect17(() => {
5487
5559
  Animated5.timing(overlayOpacity, {
5488
5560
  toValue: visible ? 1 : 0,
@@ -5528,7 +5600,7 @@ function ClaimPrizeSheet({
5528
5600
  }, [mutation.status, mutation.error]);
5529
5601
  const isMutating = mutation.status !== "idle" && mutation.status !== "success" && mutation.status !== "error";
5530
5602
  const canClaim = !isMutating && mutation.status !== "success" && !!wallet.publicKey;
5531
- const handleClaim = useCallback22(async () => {
5603
+ const handleClaim = useCallback23(async () => {
5532
5604
  if (!wallet.publicKey) return;
5533
5605
  try {
5534
5606
  await mutation.execute({
@@ -5761,7 +5833,7 @@ var styles13 = StyleSheet14.create({
5761
5833
  });
5762
5834
 
5763
5835
  // src/ui/game/ClaimButton.tsx
5764
- import { useState as useState27, useMemo as useMemo10, useCallback as useCallback23 } from "react";
5836
+ import { useState as useState28, useMemo as useMemo10, useCallback as useCallback24 } from "react";
5765
5837
  import { StyleSheet as StyleSheet15, Text as Text15, TouchableOpacity as TouchableOpacity11 } from "react-native";
5766
5838
  import { Fragment as Fragment5, jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
5767
5839
  function ClaimButton({ gameId, style, onSuccess, onError }) {
@@ -5769,7 +5841,7 @@ function ClaimButton({ gameId, style, onSuccess, onError }) {
5769
5841
  const { wallet } = useDubs();
5770
5842
  const game = useGame(gameId);
5771
5843
  const claimStatus = useHasClaimed(gameId);
5772
- const [sheetVisible, setSheetVisible] = useState27(false);
5844
+ const [sheetVisible, setSheetVisible] = useState28(false);
5773
5845
  const walletAddress = wallet.publicKey?.toBase58() ?? null;
5774
5846
  const myBet = useMemo10(() => {
5775
5847
  if (!walletAddress || !game.data?.bettors) return null;
@@ -5780,7 +5852,7 @@ function ClaimButton({ gameId, style, onSuccess, onError }) {
5780
5852
  const isWinner = isResolved && myBet != null && myBet.team === game.data?.winnerSide;
5781
5853
  const isEligible = myBet != null && isResolved && (isWinner || isRefund);
5782
5854
  const prizeAmount = isRefund ? myBet?.amount ?? 0 : game.data?.totalPool ?? 0;
5783
- const handleSuccess = useCallback23(
5855
+ const handleSuccess = useCallback24(
5784
5856
  (result) => {
5785
5857
  claimStatus.refetch();
5786
5858
  onSuccess?.(result);
@@ -5865,6 +5937,216 @@ var styles14 = StyleSheet15.create({
5865
5937
  fontWeight: "700"
5866
5938
  }
5867
5939
  });
5940
+
5941
+ // src/ui/game/EnterArcadePoolSheet.tsx
5942
+ import { useEffect as useEffect18, useRef as useRef9, useCallback as useCallback25 } from "react";
5943
+ import {
5944
+ View as View15,
5945
+ Text as Text16,
5946
+ TouchableOpacity as TouchableOpacity12,
5947
+ ActivityIndicator as ActivityIndicator9,
5948
+ Modal as Modal5,
5949
+ Animated as Animated6,
5950
+ StyleSheet as StyleSheet16,
5951
+ KeyboardAvoidingView as KeyboardAvoidingView6,
5952
+ Platform as Platform9
5953
+ } from "react-native";
5954
+ import { Fragment as Fragment6, jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
5955
+ var STATUS_LABELS5 = {
5956
+ building: "Building transaction...",
5957
+ signing: "Approve in wallet...",
5958
+ confirming: "Confirming...",
5959
+ success: "Joined!"
5960
+ };
5961
+ function EnterArcadePoolSheet({
5962
+ visible,
5963
+ onDismiss,
5964
+ pool,
5965
+ stats,
5966
+ onSuccess,
5967
+ onError
5968
+ }) {
5969
+ const t = useDubsTheme();
5970
+ const { wallet } = useDubs();
5971
+ const mutation = useEnterArcadePool();
5972
+ const overlayOpacity = useRef9(new Animated6.Value(0)).current;
5973
+ useEffect18(() => {
5974
+ Animated6.timing(overlayOpacity, {
5975
+ toValue: visible ? 1 : 0,
5976
+ duration: 250,
5977
+ useNativeDriver: true
5978
+ }).start();
5979
+ }, [visible, overlayOpacity]);
5980
+ useEffect18(() => {
5981
+ if (visible) {
5982
+ mutation.reset();
5983
+ }
5984
+ }, [visible]);
5985
+ useEffect18(() => {
5986
+ if (mutation.status === "success" && mutation.data) {
5987
+ onSuccess?.(mutation.data);
5988
+ const timer = setTimeout(() => {
5989
+ onDismiss();
5990
+ }, 1500);
5991
+ return () => clearTimeout(timer);
5992
+ }
5993
+ }, [mutation.status, mutation.data]);
5994
+ useEffect18(() => {
5995
+ if (mutation.status === "error" && mutation.error) {
5996
+ onError?.(mutation.error);
5997
+ }
5998
+ }, [mutation.status, mutation.error]);
5999
+ const buyInSol = (pool.buy_in_lamports / 1e9).toFixed(4);
6000
+ const totalPlayers = stats?.total_entries ?? pool.total_entries ?? 0;
6001
+ const topScore = stats?.top_score ?? 0;
6002
+ const potSol = (pool.buy_in_lamports * Number(totalPlayers) / 1e9).toFixed(4);
6003
+ const isMutating = mutation.status !== "idle" && mutation.status !== "success" && mutation.status !== "error";
6004
+ const canJoin = !isMutating && mutation.status !== "success";
6005
+ const handleJoin = useCallback25(async () => {
6006
+ if (!wallet.publicKey) return;
6007
+ try {
6008
+ await mutation.execute(pool.id);
6009
+ } catch {
6010
+ }
6011
+ }, [wallet.publicKey, mutation.execute, pool.id]);
6012
+ const statusLabel = STATUS_LABELS5[mutation.status] || "";
6013
+ return /* @__PURE__ */ jsxs16(
6014
+ Modal5,
6015
+ {
6016
+ visible,
6017
+ animationType: "slide",
6018
+ transparent: true,
6019
+ onRequestClose: onDismiss,
6020
+ children: [
6021
+ /* @__PURE__ */ jsx18(Animated6.View, { style: [styles15.overlay, { opacity: overlayOpacity }], children: /* @__PURE__ */ jsx18(TouchableOpacity12, { style: styles15.overlayTap, activeOpacity: 1, onPress: onDismiss }) }),
6022
+ /* @__PURE__ */ jsx18(
6023
+ KeyboardAvoidingView6,
6024
+ {
6025
+ style: styles15.keyboardView,
6026
+ behavior: Platform9.OS === "ios" ? "padding" : void 0,
6027
+ children: /* @__PURE__ */ jsx18(View15, { style: styles15.sheetPositioner, children: /* @__PURE__ */ jsxs16(View15, { style: [styles15.sheet, { backgroundColor: t.background }], children: [
6028
+ /* @__PURE__ */ jsx18(View15, { style: styles15.handleRow, children: /* @__PURE__ */ jsx18(View15, { style: [styles15.handle, { backgroundColor: t.textMuted }] }) }),
6029
+ /* @__PURE__ */ jsxs16(View15, { style: styles15.header, children: [
6030
+ /* @__PURE__ */ jsx18(Text16, { style: [styles15.headerTitle, { color: t.text }], children: "Join Pool" }),
6031
+ /* @__PURE__ */ jsx18(TouchableOpacity12, { onPress: onDismiss, activeOpacity: 0.8, children: /* @__PURE__ */ jsx18(Text16, { style: [styles15.closeButton, { color: t.textMuted }], children: "\u2715" }) })
6032
+ ] }),
6033
+ /* @__PURE__ */ jsx18(Text16, { style: [styles15.poolName, { color: t.textSecondary }], children: pool.name }),
6034
+ /* @__PURE__ */ jsxs16(View15, { style: [styles15.summaryCard, { backgroundColor: t.surface, borderColor: t.border }], children: [
6035
+ /* @__PURE__ */ jsxs16(View15, { style: styles15.summaryRow, children: [
6036
+ /* @__PURE__ */ jsx18(Text16, { style: [styles15.summaryLabel, { color: t.textMuted }], children: "Buy-in" }),
6037
+ /* @__PURE__ */ jsxs16(Text16, { style: [styles15.summaryValue, { color: t.text }], children: [
6038
+ buyInSol,
6039
+ " SOL"
6040
+ ] })
6041
+ ] }),
6042
+ /* @__PURE__ */ jsx18(View15, { style: [styles15.summarySep, { backgroundColor: t.border }] }),
6043
+ /* @__PURE__ */ jsxs16(View15, { style: styles15.summaryRow, children: [
6044
+ /* @__PURE__ */ jsx18(Text16, { style: [styles15.summaryLabel, { color: t.textMuted }], children: "Players in" }),
6045
+ /* @__PURE__ */ jsx18(Text16, { style: [styles15.summaryValue, { color: t.text }], children: totalPlayers })
6046
+ ] }),
6047
+ /* @__PURE__ */ jsx18(View15, { style: [styles15.summarySep, { backgroundColor: t.border }] }),
6048
+ /* @__PURE__ */ jsxs16(View15, { style: styles15.summaryRow, children: [
6049
+ /* @__PURE__ */ jsx18(Text16, { style: [styles15.summaryLabel, { color: t.textMuted }], children: "Current pot" }),
6050
+ /* @__PURE__ */ jsxs16(Text16, { style: [styles15.summaryValue, { color: t.success }], children: [
6051
+ potSol,
6052
+ " SOL"
6053
+ ] })
6054
+ ] }),
6055
+ /* @__PURE__ */ jsx18(View15, { style: [styles15.summarySep, { backgroundColor: t.border }] }),
6056
+ /* @__PURE__ */ jsxs16(View15, { style: styles15.summaryRow, children: [
6057
+ /* @__PURE__ */ jsx18(Text16, { style: [styles15.summaryLabel, { color: t.textMuted }], children: "Lives" }),
6058
+ /* @__PURE__ */ jsx18(Text16, { style: [styles15.summaryValue, { color: t.text }], children: pool.max_lives })
6059
+ ] }),
6060
+ topScore > 0 && /* @__PURE__ */ jsxs16(Fragment6, { children: [
6061
+ /* @__PURE__ */ jsx18(View15, { style: [styles15.summarySep, { backgroundColor: t.border }] }),
6062
+ /* @__PURE__ */ jsxs16(View15, { style: styles15.summaryRow, children: [
6063
+ /* @__PURE__ */ jsx18(Text16, { style: [styles15.summaryLabel, { color: t.textMuted }], children: "Top score" }),
6064
+ /* @__PURE__ */ jsx18(Text16, { style: [styles15.summaryValue, { color: t.text }], children: topScore })
6065
+ ] })
6066
+ ] })
6067
+ ] }),
6068
+ mutation.error && /* @__PURE__ */ jsx18(View15, { style: [styles15.errorBox, { backgroundColor: t.errorBg, borderColor: t.errorBorder }], children: /* @__PURE__ */ jsx18(Text16, { style: [styles15.errorText, { color: t.errorText }], children: mutation.error.message }) }),
6069
+ /* @__PURE__ */ jsx18(
6070
+ TouchableOpacity12,
6071
+ {
6072
+ style: [
6073
+ styles15.ctaButton,
6074
+ { backgroundColor: canJoin ? t.accent : t.border }
6075
+ ],
6076
+ disabled: !canJoin,
6077
+ onPress: handleJoin,
6078
+ activeOpacity: 0.8,
6079
+ children: isMutating ? /* @__PURE__ */ jsxs16(View15, { style: styles15.ctaLoading, children: [
6080
+ /* @__PURE__ */ jsx18(ActivityIndicator9, { size: "small", color: "#FFFFFF" }),
6081
+ /* @__PURE__ */ jsx18(Text16, { style: styles15.ctaText, children: statusLabel })
6082
+ ] }) : mutation.status === "success" ? /* @__PURE__ */ jsx18(Text16, { style: styles15.ctaText, children: "Joined!" }) : /* @__PURE__ */ jsx18(Text16, { style: [styles15.ctaText, !canJoin && { opacity: 0.5 }], children: `Join Pool \u2014 ${buyInSol} SOL` })
6083
+ }
6084
+ )
6085
+ ] }) })
6086
+ }
6087
+ )
6088
+ ]
6089
+ }
6090
+ );
6091
+ }
6092
+ var styles15 = StyleSheet16.create({
6093
+ overlay: {
6094
+ ...StyleSheet16.absoluteFillObject,
6095
+ backgroundColor: "rgba(0,0,0,0.5)"
6096
+ },
6097
+ overlayTap: { flex: 1 },
6098
+ keyboardView: { flex: 1, justifyContent: "flex-end" },
6099
+ sheetPositioner: { justifyContent: "flex-end" },
6100
+ sheet: {
6101
+ borderTopLeftRadius: 24,
6102
+ borderTopRightRadius: 24,
6103
+ paddingHorizontal: 20,
6104
+ paddingBottom: 40
6105
+ },
6106
+ handleRow: { alignItems: "center", paddingTop: 10, paddingBottom: 8 },
6107
+ handle: { width: 36, height: 4, borderRadius: 2, opacity: 0.4 },
6108
+ header: {
6109
+ flexDirection: "row",
6110
+ alignItems: "center",
6111
+ justifyContent: "space-between",
6112
+ paddingVertical: 12
6113
+ },
6114
+ headerTitle: { fontSize: 20, fontWeight: "700" },
6115
+ closeButton: { fontSize: 20, padding: 4 },
6116
+ poolName: { fontSize: 15, fontWeight: "600", marginBottom: 8 },
6117
+ summaryCard: {
6118
+ marginTop: 12,
6119
+ borderRadius: 16,
6120
+ borderWidth: 1,
6121
+ overflow: "hidden"
6122
+ },
6123
+ summaryRow: {
6124
+ flexDirection: "row",
6125
+ alignItems: "center",
6126
+ justifyContent: "space-between",
6127
+ paddingHorizontal: 16,
6128
+ paddingVertical: 14
6129
+ },
6130
+ summaryLabel: { fontSize: 14 },
6131
+ summaryValue: { fontSize: 15, fontWeight: "700" },
6132
+ summarySep: { height: 1, marginHorizontal: 16 },
6133
+ errorBox: {
6134
+ marginTop: 16,
6135
+ borderRadius: 12,
6136
+ borderWidth: 1,
6137
+ padding: 12
6138
+ },
6139
+ errorText: { fontSize: 13, fontWeight: "500" },
6140
+ ctaButton: {
6141
+ marginTop: 20,
6142
+ height: 56,
6143
+ borderRadius: 14,
6144
+ justifyContent: "center",
6145
+ alignItems: "center"
6146
+ },
6147
+ ctaText: { color: "#FFFFFF", fontSize: 16, fontWeight: "700" },
6148
+ ctaLoading: { flexDirection: "row", alignItems: "center", gap: 10 }
6149
+ });
5868
6150
  export {
5869
6151
  AuthGate,
5870
6152
  ClaimButton,
@@ -5876,6 +6158,7 @@ export {
5876
6158
  DubsApiError,
5877
6159
  DubsClient,
5878
6160
  DubsProvider,
6161
+ EnterArcadePoolSheet,
5879
6162
  GamePoster,
5880
6163
  JoinGameButton,
5881
6164
  JoinGameSheet,
@@ -5907,6 +6190,7 @@ export {
5907
6190
  useCreateGame,
5908
6191
  useDubs,
5909
6192
  useDubsTheme,
6193
+ useEnterArcadePool,
5910
6194
  useEvents,
5911
6195
  useGame,
5912
6196
  useGames,