@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.js CHANGED
@@ -40,6 +40,7 @@ __export(index_exports, {
40
40
  DubsApiError: () => DubsApiError,
41
41
  DubsClient: () => DubsClient,
42
42
  DubsProvider: () => DubsProvider,
43
+ EnterArcadePoolSheet: () => EnterArcadePoolSheet,
43
44
  GamePoster: () => GamePoster,
44
45
  JoinGameButton: () => JoinGameButton,
45
46
  JoinGameSheet: () => JoinGameSheet,
@@ -71,6 +72,7 @@ __export(index_exports, {
71
72
  useCreateGame: () => useCreateGame,
72
73
  useDubs: () => useDubs,
73
74
  useDubsTheme: () => useDubsTheme,
75
+ useEnterArcadePool: () => useEnterArcadePool,
74
76
  useEvents: () => useEvents,
75
77
  useGame: () => useGame,
76
78
  useGames: () => useGames,
@@ -607,6 +609,20 @@ var DubsClient = class {
607
609
  );
608
610
  return { pool: res.pool, stats: res.stats };
609
611
  }
612
+ /** Build unsigned entry transaction for an arcade pool */
613
+ async buildArcadeEntry(poolId, walletAddress) {
614
+ const res = await this.request(
615
+ "POST",
616
+ `/arcade/pools/${poolId}/build-enter`,
617
+ { walletAddress }
618
+ );
619
+ return {
620
+ transaction: res.transaction,
621
+ poolId: res.poolId,
622
+ amount: res.amount,
623
+ destination: res.destination
624
+ };
625
+ }
610
626
  async enterArcadePool(poolId, params) {
611
627
  const res = await this.request(
612
628
  "POST",
@@ -700,7 +716,7 @@ function createSecureStoreStorage() {
700
716
  }
701
717
 
702
718
  // src/provider.tsx
703
- var import_react21 = require("react");
719
+ var import_react22 = require("react");
704
720
 
705
721
  // src/ui/theme.ts
706
722
  var import_react = require("react");
@@ -1758,7 +1774,7 @@ function ManagedWalletProvider({
1758
1774
  }
1759
1775
 
1760
1776
  // src/ui/AuthGate.tsx
1761
- var import_react20 = __toESM(require("react"));
1777
+ var import_react21 = __toESM(require("react"));
1762
1778
  var import_react_native8 = require("react-native");
1763
1779
 
1764
1780
  // src/hooks/useEvents.ts
@@ -2722,6 +2738,64 @@ function useArcadeGame(poolId, maxLives = 3) {
2722
2738
  };
2723
2739
  }
2724
2740
 
2741
+ // src/hooks/useEnterArcadePool.ts
2742
+ var import_react20 = require("react");
2743
+ function useEnterArcadePool() {
2744
+ const { client, wallet, connection } = useDubs();
2745
+ const { user } = useAuth();
2746
+ const [status, setStatus] = (0, import_react20.useState)("idle");
2747
+ const [error, setError] = (0, import_react20.useState)(null);
2748
+ const [data, setData] = (0, import_react20.useState)(null);
2749
+ const reset = (0, import_react20.useCallback)(() => {
2750
+ setStatus("idle");
2751
+ setError(null);
2752
+ setData(null);
2753
+ }, []);
2754
+ const execute = (0, import_react20.useCallback)(async (poolId) => {
2755
+ if (!wallet.publicKey) throw new Error("Wallet not connected");
2756
+ const walletAddress = wallet.publicKey.toBase58();
2757
+ setStatus("building");
2758
+ setError(null);
2759
+ setData(null);
2760
+ try {
2761
+ console.log("[useEnterArcadePool] Step 1: Building transaction...", { poolId, walletAddress });
2762
+ const buildResult = await client.buildArcadeEntry(poolId, walletAddress);
2763
+ console.log("[useEnterArcadePool] Step 1 done:", { poolId: buildResult.poolId, amount: buildResult.amount });
2764
+ setStatus("signing");
2765
+ console.log("[useEnterArcadePool] Step 2: Signing and sending...");
2766
+ const signature = await signAndSendBase64Transaction(
2767
+ buildResult.transaction,
2768
+ wallet,
2769
+ connection
2770
+ );
2771
+ console.log("[useEnterArcadePool] Step 2 done. Signature:", signature);
2772
+ setStatus("confirming");
2773
+ console.log("[useEnterArcadePool] Step 3: Confirming with backend...");
2774
+ const entry = await client.enterArcadePool(poolId, {
2775
+ walletAddress,
2776
+ txSignature: signature
2777
+ });
2778
+ console.log("[useEnterArcadePool] Step 3 done. Entry recorded.");
2779
+ const result = {
2780
+ poolId,
2781
+ signature,
2782
+ entry
2783
+ };
2784
+ setData(result);
2785
+ setStatus("success");
2786
+ console.log("[useEnterArcadePool] Complete!");
2787
+ return result;
2788
+ } catch (err) {
2789
+ console.error("[useEnterArcadePool] FAILED at status:", status, err);
2790
+ const e = err instanceof Error ? err : new Error(String(err));
2791
+ setError(e);
2792
+ setStatus("error");
2793
+ throw e;
2794
+ }
2795
+ }, [client, wallet, connection]);
2796
+ return { execute, status, error, data, reset };
2797
+ }
2798
+
2725
2799
  // src/ui/AvatarEditor.tsx
2726
2800
  var import_react_native7 = require("react-native");
2727
2801
  var import_jsx_runtime3 = require("react/jsx-runtime");
@@ -2882,11 +2956,11 @@ function AuthGate({
2882
2956
  }) {
2883
2957
  const { client, pushEnabled } = useDubs();
2884
2958
  const auth = useAuth();
2885
- const [phase, setPhase] = (0, import_react20.useState)("init");
2886
- const [registrationPhase, setRegistrationPhase] = (0, import_react20.useState)(false);
2887
- const [showPushSetup, setShowPushSetup] = (0, import_react20.useState)(false);
2888
- const [isRestoredSession, setIsRestoredSession] = (0, import_react20.useState)(false);
2889
- (0, import_react20.useEffect)(() => {
2959
+ const [phase, setPhase] = (0, import_react21.useState)("init");
2960
+ const [registrationPhase, setRegistrationPhase] = (0, import_react21.useState)(false);
2961
+ const [showPushSetup, setShowPushSetup] = (0, import_react21.useState)(false);
2962
+ const [isRestoredSession, setIsRestoredSession] = (0, import_react21.useState)(false);
2963
+ (0, import_react21.useEffect)(() => {
2890
2964
  let cancelled = false;
2891
2965
  (async () => {
2892
2966
  try {
@@ -2913,23 +2987,23 @@ function AuthGate({
2913
2987
  cancelled = true;
2914
2988
  };
2915
2989
  }, []);
2916
- (0, import_react20.useEffect)(() => {
2990
+ (0, import_react21.useEffect)(() => {
2917
2991
  if (auth.status === "needsRegistration") setRegistrationPhase(true);
2918
2992
  }, [auth.status]);
2919
- (0, import_react20.useEffect)(() => {
2993
+ (0, import_react21.useEffect)(() => {
2920
2994
  if (pushEnabled && auth.status === "authenticated" && registrationPhase && !isRestoredSession) {
2921
2995
  setShowPushSetup(true);
2922
2996
  }
2923
2997
  }, [pushEnabled, auth.status, registrationPhase, isRestoredSession]);
2924
- (0, import_react20.useEffect)(() => {
2998
+ (0, import_react21.useEffect)(() => {
2925
2999
  if (auth.token) onSaveToken(auth.token);
2926
3000
  }, [auth.token]);
2927
- const retry = (0, import_react20.useCallback)(() => {
3001
+ const retry = (0, import_react21.useCallback)(() => {
2928
3002
  setRegistrationPhase(false);
2929
3003
  auth.reset();
2930
3004
  auth.authenticate();
2931
3005
  }, [auth]);
2932
- const handleRegister = (0, import_react20.useCallback)(
3006
+ const handleRegister = (0, import_react21.useCallback)(
2933
3007
  (username, referralCode, avatarUrl) => {
2934
3008
  auth.register(username, referralCode, avatarUrl);
2935
3009
  },
@@ -3021,7 +3095,7 @@ function DefaultErrorScreen({ error, onRetry, appName, accentColor }) {
3021
3095
  function StepIndicator({ currentStep }) {
3022
3096
  const t = useDubsTheme();
3023
3097
  const steps = [0, 1, 2, 3];
3024
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native8.View, { style: s.stepRow, children: steps.map((i) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react20.default.Fragment, { children: [
3098
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native8.View, { style: s.stepRow, children: steps.map((i) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react21.default.Fragment, { children: [
3025
3099
  i > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native8.View, { style: [s.stepLine, { backgroundColor: i <= currentStep ? t.success : t.border }] }),
3026
3100
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3027
3101
  import_react_native8.View,
@@ -3045,20 +3119,20 @@ function DefaultRegistrationScreen({
3045
3119
  }) {
3046
3120
  const t = useDubsTheme();
3047
3121
  const accent = accentColor || t.accent;
3048
- const [step, setStep] = (0, import_react20.useState)(0);
3049
- const [avatarSeed, setAvatarSeed] = (0, import_react20.useState)(generateSeed);
3050
- const [avatarStyle, setAvatarStyle] = (0, import_react20.useState)("adventurer");
3051
- const [avatarBg, setAvatarBg] = (0, import_react20.useState)("1a1a2e");
3052
- const [showStyles, setShowStyles] = (0, import_react20.useState)(false);
3053
- const [username, setUsername] = (0, import_react20.useState)("");
3054
- const [referralCode, setReferralCode] = (0, import_react20.useState)("");
3055
- const [checking, setChecking] = (0, import_react20.useState)(false);
3056
- const [availability, setAvailability] = (0, import_react20.useState)(null);
3057
- const debounceRef = (0, import_react20.useRef)(null);
3058
- const fadeAnim = (0, import_react20.useRef)(new import_react_native8.Animated.Value(1)).current;
3059
- const slideAnim = (0, import_react20.useRef)(new import_react_native8.Animated.Value(0)).current;
3122
+ const [step, setStep] = (0, import_react21.useState)(0);
3123
+ const [avatarSeed, setAvatarSeed] = (0, import_react21.useState)(generateSeed);
3124
+ const [avatarStyle, setAvatarStyle] = (0, import_react21.useState)("adventurer");
3125
+ const [avatarBg, setAvatarBg] = (0, import_react21.useState)("1a1a2e");
3126
+ const [showStyles, setShowStyles] = (0, import_react21.useState)(false);
3127
+ const [username, setUsername] = (0, import_react21.useState)("");
3128
+ const [referralCode, setReferralCode] = (0, import_react21.useState)("");
3129
+ const [checking, setChecking] = (0, import_react21.useState)(false);
3130
+ const [availability, setAvailability] = (0, import_react21.useState)(null);
3131
+ const debounceRef = (0, import_react21.useRef)(null);
3132
+ const fadeAnim = (0, import_react21.useRef)(new import_react_native8.Animated.Value(1)).current;
3133
+ const slideAnim = (0, import_react21.useRef)(new import_react_native8.Animated.Value(0)).current;
3060
3134
  const avatarUrl = getAvatarUrl(avatarStyle, avatarSeed, avatarBg);
3061
- (0, import_react20.useEffect)(() => {
3135
+ (0, import_react21.useEffect)(() => {
3062
3136
  if (debounceRef.current) clearTimeout(debounceRef.current);
3063
3137
  const trimmed = username.trim();
3064
3138
  if (trimmed.length < 3) {
@@ -3081,7 +3155,7 @@ function DefaultRegistrationScreen({
3081
3155
  if (debounceRef.current) clearTimeout(debounceRef.current);
3082
3156
  };
3083
3157
  }, [username, client]);
3084
- const animateToStep = (0, import_react20.useCallback)((newStep) => {
3158
+ const animateToStep = (0, import_react21.useCallback)((newStep) => {
3085
3159
  const dir = newStep > step ? 1 : -1;
3086
3160
  import_react_native8.Keyboard.dismiss();
3087
3161
  import_react_native8.Animated.parallel([
@@ -3320,8 +3394,8 @@ function DefaultRegistrationScreen({
3320
3394
  }
3321
3395
  function PushTokenRestorer() {
3322
3396
  const push = usePushNotifications();
3323
- const restored = (0, import_react20.useRef)(false);
3324
- (0, import_react20.useEffect)(() => {
3397
+ const restored = (0, import_react21.useRef)(false);
3398
+ (0, import_react21.useEffect)(() => {
3325
3399
  if (restored.current) return;
3326
3400
  restored.current = true;
3327
3401
  push.restoreIfGranted();
@@ -3336,9 +3410,9 @@ function PushSetupScreen({
3336
3410
  const t = useDubsTheme();
3337
3411
  const accent = accentColor || t.accent;
3338
3412
  const push = usePushNotifications();
3339
- const fadeAnim = (0, import_react20.useRef)(new import_react_native8.Animated.Value(0)).current;
3340
- const slideAnim = (0, import_react20.useRef)(new import_react_native8.Animated.Value(30)).current;
3341
- (0, import_react20.useEffect)(() => {
3413
+ const fadeAnim = (0, import_react21.useRef)(new import_react_native8.Animated.Value(0)).current;
3414
+ const slideAnim = (0, import_react21.useRef)(new import_react_native8.Animated.Value(30)).current;
3415
+ (0, import_react21.useEffect)(() => {
3342
3416
  import_react_native8.Animated.parallel([
3343
3417
  import_react_native8.Animated.timing(fadeAnim, { toValue: 1, duration: 300, useNativeDriver: true }),
3344
3418
  import_react_native8.Animated.timing(slideAnim, { toValue: 0, duration: 300, useNativeDriver: true })
@@ -3474,7 +3548,7 @@ var s = import_react_native8.StyleSheet.create({
3474
3548
 
3475
3549
  // src/provider.tsx
3476
3550
  var import_jsx_runtime5 = require("react/jsx-runtime");
3477
- var DubsContext = (0, import_react21.createContext)(null);
3551
+ var DubsContext = (0, import_react22.createContext)(null);
3478
3552
  function DubsProvider({
3479
3553
  apiKey,
3480
3554
  children,
@@ -3496,11 +3570,11 @@ function DubsProvider({
3496
3570
  const config = NETWORK_CONFIG[network];
3497
3571
  const baseUrl = baseUrlOverride || config.baseUrl;
3498
3572
  const rpcUrl = rpcUrlOverride || config.rpcUrl;
3499
- const client = (0, import_react21.useMemo)(() => new DubsClient({ apiKey, baseUrl }), [apiKey, baseUrl]);
3500
- const storage = (0, import_react21.useMemo)(() => tokenStorage || createSecureStoreStorage(), [tokenStorage]);
3501
- const [uiConfig, setUiConfig] = (0, import_react21.useState)(null);
3502
- const [resolvedNetwork, setResolvedNetwork] = (0, import_react21.useState)(network);
3503
- (0, import_react21.useEffect)(() => {
3573
+ const client = (0, import_react22.useMemo)(() => new DubsClient({ apiKey, baseUrl }), [apiKey, baseUrl]);
3574
+ const storage = (0, import_react22.useMemo)(() => tokenStorage || createSecureStoreStorage(), [tokenStorage]);
3575
+ const [uiConfig, setUiConfig] = (0, import_react22.useState)(null);
3576
+ const [resolvedNetwork, setResolvedNetwork] = (0, import_react22.useState)(network);
3577
+ (0, import_react22.useEffect)(() => {
3504
3578
  client.getAppConfig().then((cfg) => {
3505
3579
  console.log("[DubsProvider] UI config loaded:", JSON.stringify(cfg));
3506
3580
  setUiConfig(cfg);
@@ -3516,7 +3590,7 @@ function DubsProvider({
3516
3590
  const resolvedConfig = NETWORK_CONFIG[resolvedNetwork];
3517
3591
  const resolvedRpcUrl = rpcUrlOverride || resolvedConfig.rpcUrl;
3518
3592
  const cluster = resolvedConfig.cluster;
3519
- const connection = (0, import_react21.useMemo)(() => new import_web34.Connection(resolvedRpcUrl, { commitment: "confirmed" }), [resolvedRpcUrl]);
3593
+ const connection = (0, import_react22.useMemo)(() => new import_web34.Connection(resolvedRpcUrl, { commitment: "confirmed" }), [resolvedRpcUrl]);
3520
3594
  if (uiConfig === null) return null;
3521
3595
  const themeOverrides = {};
3522
3596
  if (uiConfig.accentColor) {
@@ -3592,11 +3666,11 @@ function ManagedInner({
3592
3666
  children
3593
3667
  }) {
3594
3668
  const managedDisconnect = useDisconnect();
3595
- const disconnect = (0, import_react21.useCallback)(async () => {
3669
+ const disconnect = (0, import_react22.useCallback)(async () => {
3596
3670
  client.setToken(null);
3597
3671
  await managedDisconnect?.();
3598
3672
  }, [client, managedDisconnect]);
3599
- const value = (0, import_react21.useMemo)(
3673
+ const value = (0, import_react22.useMemo)(
3600
3674
  () => ({ client, wallet, connection, appName, network, disconnect, uiConfig, pushEnabled }),
3601
3675
  [client, wallet, connection, appName, network, disconnect, uiConfig, pushEnabled]
3602
3676
  );
@@ -3633,13 +3707,13 @@ function ExternalWalletProvider({
3633
3707
  pushEnabled,
3634
3708
  children
3635
3709
  }) {
3636
- const disconnect = (0, import_react21.useCallback)(async () => {
3710
+ const disconnect = (0, import_react22.useCallback)(async () => {
3637
3711
  client.setToken(null);
3638
3712
  await storage.deleteItem(STORAGE_KEYS.JWT_TOKEN).catch(() => {
3639
3713
  });
3640
3714
  await wallet.disconnect?.();
3641
3715
  }, [client, storage, wallet]);
3642
- const value = (0, import_react21.useMemo)(
3716
+ const value = (0, import_react22.useMemo)(
3643
3717
  () => ({ client, wallet, connection, appName, network, disconnect, uiConfig, pushEnabled }),
3644
3718
  [client, wallet, connection, appName, network, disconnect, uiConfig, pushEnabled]
3645
3719
  );
@@ -3664,19 +3738,19 @@ function ExternalWalletProvider({
3664
3738
  ) });
3665
3739
  }
3666
3740
  function useDubs() {
3667
- const ctx = (0, import_react21.useContext)(DubsContext);
3741
+ const ctx = (0, import_react22.useContext)(DubsContext);
3668
3742
  if (!ctx) {
3669
3743
  throw new Error("useDubs must be used within a <DubsProvider>");
3670
3744
  }
3671
3745
  return ctx;
3672
3746
  }
3673
3747
  function useAppConfig() {
3674
- const ctx = (0, import_react21.useContext)(DubsContext);
3748
+ const ctx = (0, import_react22.useContext)(DubsContext);
3675
3749
  return ctx?.uiConfig || {};
3676
3750
  }
3677
3751
 
3678
3752
  // src/ui/UserProfileCard.tsx
3679
- var import_react22 = require("react");
3753
+ var import_react23 = require("react");
3680
3754
  var import_react_native9 = require("react-native");
3681
3755
  var import_jsx_runtime6 = require("react/jsx-runtime");
3682
3756
  function truncateAddress(address, chars = 4) {
@@ -3696,7 +3770,7 @@ function UserProfileCard({
3696
3770
  memberSince
3697
3771
  }) {
3698
3772
  const t = useDubsTheme();
3699
- const imageUri = (0, import_react22.useMemo)(
3773
+ const imageUri = (0, import_react23.useMemo)(
3700
3774
  () => ensurePngAvatar(avatarUrl) || `https://api.dicebear.com/9.x/avataaars/png?seed=${walletAddress}&size=128`,
3701
3775
  [avatarUrl, walletAddress]
3702
3776
  );
@@ -3889,7 +3963,7 @@ var styles4 = import_react_native10.StyleSheet.create({
3889
3963
  });
3890
3964
 
3891
3965
  // src/ui/UserProfileSheet.tsx
3892
- var import_react23 = require("react");
3966
+ var import_react24 = require("react");
3893
3967
  var import_react_native11 = require("react-native");
3894
3968
  var import_jsx_runtime8 = require("react/jsx-runtime");
3895
3969
  function truncateAddress3(address, chars = 4) {
@@ -3907,31 +3981,31 @@ function UserProfileSheet({
3907
3981
  const { client } = useDubs();
3908
3982
  const { refreshUser } = useAuth();
3909
3983
  const push = usePushNotifications();
3910
- const overlayOpacity = (0, import_react23.useRef)(new import_react_native11.Animated.Value(0)).current;
3911
- const parsed = (0, import_react23.useMemo)(() => parseAvatarUrl(user.avatar), [user.avatar]);
3912
- const [avatarStyle, setAvatarStyle] = (0, import_react23.useState)(parsed.style);
3913
- const [avatarSeed, setAvatarSeed] = (0, import_react23.useState)(parsed.seed);
3914
- const [bgColor, setBgColor] = (0, import_react23.useState)(parsed.bg);
3915
- const [saving, setSaving] = (0, import_react23.useState)(false);
3916
- const [error, setError] = (0, import_react23.useState)(null);
3917
- (0, import_react23.useEffect)(() => {
3984
+ const overlayOpacity = (0, import_react24.useRef)(new import_react_native11.Animated.Value(0)).current;
3985
+ const parsed = (0, import_react24.useMemo)(() => parseAvatarUrl(user.avatar), [user.avatar]);
3986
+ const [avatarStyle, setAvatarStyle] = (0, import_react24.useState)(parsed.style);
3987
+ const [avatarSeed, setAvatarSeed] = (0, import_react24.useState)(parsed.seed);
3988
+ const [bgColor, setBgColor] = (0, import_react24.useState)(parsed.bg);
3989
+ const [saving, setSaving] = (0, import_react24.useState)(false);
3990
+ const [error, setError] = (0, import_react24.useState)(null);
3991
+ (0, import_react24.useEffect)(() => {
3918
3992
  const p = parseAvatarUrl(user.avatar);
3919
3993
  setAvatarStyle(p.style);
3920
3994
  setAvatarSeed(p.seed);
3921
3995
  setBgColor(p.bg);
3922
3996
  }, [user.avatar]);
3923
- (0, import_react23.useEffect)(() => {
3997
+ (0, import_react24.useEffect)(() => {
3924
3998
  import_react_native11.Animated.timing(overlayOpacity, {
3925
3999
  toValue: visible ? 1 : 0,
3926
4000
  duration: 250,
3927
4001
  useNativeDriver: true
3928
4002
  }).start();
3929
4003
  }, [visible, overlayOpacity]);
3930
- (0, import_react23.useEffect)(() => {
4004
+ (0, import_react24.useEffect)(() => {
3931
4005
  if (visible) setError(null);
3932
4006
  }, [visible]);
3933
4007
  const currentAvatarUrl = getAvatarUrl(avatarStyle, avatarSeed, bgColor);
3934
- const saveAvatar = (0, import_react23.useCallback)(async (newUrl) => {
4008
+ const saveAvatar = (0, import_react24.useCallback)(async (newUrl) => {
3935
4009
  setSaving(true);
3936
4010
  setError(null);
3937
4011
  try {
@@ -3944,16 +4018,16 @@ function UserProfileSheet({
3944
4018
  setSaving(false);
3945
4019
  }
3946
4020
  }, [client, refreshUser, onAvatarUpdated]);
3947
- const handleStyleChange = (0, import_react23.useCallback)((style) => {
4021
+ const handleStyleChange = (0, import_react24.useCallback)((style) => {
3948
4022
  setAvatarStyle(style);
3949
4023
  saveAvatar(getAvatarUrl(style, avatarSeed, bgColor));
3950
4024
  }, [avatarSeed, bgColor, saveAvatar]);
3951
- const handleShuffle = (0, import_react23.useCallback)(() => {
4025
+ const handleShuffle = (0, import_react24.useCallback)(() => {
3952
4026
  const newSeed = generateSeed();
3953
4027
  setAvatarSeed(newSeed);
3954
4028
  saveAvatar(getAvatarUrl(avatarStyle, newSeed, bgColor));
3955
4029
  }, [avatarStyle, bgColor, saveAvatar]);
3956
- const handleBgChange = (0, import_react23.useCallback)((color) => {
4030
+ const handleBgChange = (0, import_react24.useCallback)((color) => {
3957
4031
  setBgColor(color);
3958
4032
  saveAvatar(getAvatarUrl(avatarStyle, avatarSeed, color));
3959
4033
  }, [avatarStyle, avatarSeed, saveAvatar]);
@@ -4233,7 +4307,7 @@ var styles5 = import_react_native11.StyleSheet.create({
4233
4307
  });
4234
4308
 
4235
4309
  // src/ui/game/GamePoster.tsx
4236
- var import_react24 = require("react");
4310
+ var import_react25 = require("react");
4237
4311
  var import_react_native12 = require("react-native");
4238
4312
  var import_jsx_runtime9 = require("react/jsx-runtime");
4239
4313
  function computeCountdown(lockTimestamp) {
@@ -4283,7 +4357,7 @@ function GamePoster({ game, ImageComponent }) {
4283
4357
  ] });
4284
4358
  }
4285
4359
  function TeamLogoInternal({ url, size, Img }) {
4286
- const [failed, setFailed] = (0, import_react24.useState)(false);
4360
+ const [failed, setFailed] = (0, import_react25.useState)(false);
4287
4361
  if (!url || failed) {
4288
4362
  return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native12.View, { style: [styles6.logoPlaceholder, { width: size, height: size, borderRadius: size / 2 }] });
4289
4363
  }
@@ -4384,7 +4458,7 @@ var styles6 = import_react_native12.StyleSheet.create({
4384
4458
  });
4385
4459
 
4386
4460
  // src/ui/game/LivePoolsCard.tsx
4387
- var import_react25 = require("react");
4461
+ var import_react26 = require("react");
4388
4462
  var import_react_native13 = require("react-native");
4389
4463
  var import_jsx_runtime10 = require("react/jsx-runtime");
4390
4464
  function LivePoolsCard({
@@ -4400,7 +4474,7 @@ function LivePoolsCard({
4400
4474
  const homePool = game.homePool || 0;
4401
4475
  const awayPool = game.awayPool || 0;
4402
4476
  const totalPool = game.totalPool || 0;
4403
- const { homePercent, awayPercent, homeOdds, awayOdds } = (0, import_react25.useMemo)(() => {
4477
+ const { homePercent, awayPercent, homeOdds, awayOdds } = (0, import_react26.useMemo)(() => {
4404
4478
  return {
4405
4479
  homePercent: totalPool > 0 ? homePool / totalPool * 100 : 50,
4406
4480
  awayPercent: totalPool > 0 ? awayPool / totalPool * 100 : 50,
@@ -4463,7 +4537,7 @@ var styles7 = import_react_native13.StyleSheet.create({
4463
4537
  });
4464
4538
 
4465
4539
  // src/ui/game/PickWinnerCard.tsx
4466
- var import_react26 = require("react");
4540
+ var import_react27 = require("react");
4467
4541
  var import_react_native14 = require("react-native");
4468
4542
  var import_jsx_runtime11 = require("react/jsx-runtime");
4469
4543
  function PickWinnerCard({
@@ -4481,7 +4555,7 @@ function PickWinnerCard({
4481
4555
  const totalPool = game.totalPool || 0;
4482
4556
  const homePool = game.homePool || 0;
4483
4557
  const awayPool = game.awayPool || 0;
4484
- const { homeOdds, awayOdds, homeBets, awayBets } = (0, import_react26.useMemo)(() => ({
4558
+ const { homeOdds, awayOdds, homeBets, awayBets } = (0, import_react27.useMemo)(() => ({
4485
4559
  homeOdds: homePool > 0 ? (totalPool / homePool).toFixed(2) : "\u2014",
4486
4560
  awayOdds: awayPool > 0 ? (totalPool / awayPool).toFixed(2) : "\u2014",
4487
4561
  homeBets: bettors.filter((b) => b.team === "home").length,
@@ -4534,7 +4608,7 @@ function TeamOption({
4534
4608
  ImageComponent,
4535
4609
  t
4536
4610
  }) {
4537
- const [imgFailed, setImgFailed] = (0, import_react26.useState)(false);
4611
+ const [imgFailed, setImgFailed] = (0, import_react27.useState)(false);
4538
4612
  const Img = ImageComponent || require("react-native").Image;
4539
4613
  const showImage = imageUrl && !imgFailed;
4540
4614
  return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
@@ -4575,7 +4649,7 @@ var styles8 = import_react_native14.StyleSheet.create({
4575
4649
  });
4576
4650
 
4577
4651
  // src/ui/game/PlayersCard.tsx
4578
- var import_react27 = require("react");
4652
+ var import_react28 = require("react");
4579
4653
  var import_react_native15 = require("react-native");
4580
4654
  var import_jsx_runtime12 = require("react/jsx-runtime");
4581
4655
  function truncateWallet(addr, chars) {
@@ -4624,7 +4698,7 @@ function BettorRow({
4624
4698
  ImageComponent,
4625
4699
  t
4626
4700
  }) {
4627
- const [imgFailed, setImgFailed] = (0, import_react27.useState)(false);
4701
+ const [imgFailed, setImgFailed] = (0, import_react28.useState)(false);
4628
4702
  const Img = ImageComponent || require("react-native").Image;
4629
4703
  const showAvatar = bettor.avatar && !imgFailed;
4630
4704
  return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native15.View, { style: [styles9.row, !isFirst && { borderTopColor: t.border, borderTopWidth: 1 }], children: [
@@ -4651,7 +4725,7 @@ var styles9 = import_react_native15.StyleSheet.create({
4651
4725
  });
4652
4726
 
4653
4727
  // src/ui/game/JoinGameButton.tsx
4654
- var import_react28 = require("react");
4728
+ var import_react29 = require("react");
4655
4729
  var import_react_native16 = require("react-native");
4656
4730
  var import_jsx_runtime13 = require("react/jsx-runtime");
4657
4731
  var STATUS_LABELS = {
@@ -4662,7 +4736,7 @@ var STATUS_LABELS = {
4662
4736
  };
4663
4737
  function JoinGameButton({ game, walletAddress, selectedTeam, status, onJoin }) {
4664
4738
  const t = useDubsTheme();
4665
- const alreadyJoined = (0, import_react28.useMemo)(() => {
4739
+ const alreadyJoined = (0, import_react29.useMemo)(() => {
4666
4740
  if (!walletAddress) return false;
4667
4741
  return (game.bettors || []).some((b) => b.wallet === walletAddress);
4668
4742
  }, [game.bettors, walletAddress]);
@@ -4703,7 +4777,7 @@ var styles10 = import_react_native16.StyleSheet.create({
4703
4777
  });
4704
4778
 
4705
4779
  // src/ui/game/CreateCustomGameSheet.tsx
4706
- var import_react29 = require("react");
4780
+ var import_react30 = require("react");
4707
4781
  var import_react_native17 = require("react-native");
4708
4782
  var import_jsx_runtime14 = require("react/jsx-runtime");
4709
4783
  var STATUS_LABELS2 = {
@@ -4729,18 +4803,18 @@ function CreateCustomGameSheet({
4729
4803
  const t = useDubsTheme();
4730
4804
  const { wallet } = useDubs();
4731
4805
  const mutation = useCreateCustomGame();
4732
- const [selectedAmount, setSelectedAmount] = (0, import_react29.useState)(null);
4733
- const [customAmount, setCustomAmount] = (0, import_react29.useState)("");
4734
- const [isCustom, setIsCustom] = (0, import_react29.useState)(false);
4735
- const overlayOpacity = (0, import_react29.useRef)(new import_react_native17.Animated.Value(0)).current;
4736
- (0, import_react29.useEffect)(() => {
4806
+ const [selectedAmount, setSelectedAmount] = (0, import_react30.useState)(null);
4807
+ const [customAmount, setCustomAmount] = (0, import_react30.useState)("");
4808
+ const [isCustom, setIsCustom] = (0, import_react30.useState)(false);
4809
+ const overlayOpacity = (0, import_react30.useRef)(new import_react_native17.Animated.Value(0)).current;
4810
+ (0, import_react30.useEffect)(() => {
4737
4811
  import_react_native17.Animated.timing(overlayOpacity, {
4738
4812
  toValue: visible ? 1 : 0,
4739
4813
  duration: 250,
4740
4814
  useNativeDriver: true
4741
4815
  }).start();
4742
4816
  }, [visible, overlayOpacity]);
4743
- (0, import_react29.useEffect)(() => {
4817
+ (0, import_react30.useEffect)(() => {
4744
4818
  if (visible) {
4745
4819
  setSelectedAmount(defaultAmount ?? null);
4746
4820
  setCustomAmount("");
@@ -4748,7 +4822,7 @@ function CreateCustomGameSheet({
4748
4822
  mutation.reset();
4749
4823
  }
4750
4824
  }, [visible]);
4751
- (0, import_react29.useEffect)(() => {
4825
+ (0, import_react30.useEffect)(() => {
4752
4826
  if (mutation.status === "success" && mutation.data) {
4753
4827
  onSuccess?.(mutation.data);
4754
4828
  const timer = setTimeout(() => {
@@ -4757,23 +4831,23 @@ function CreateCustomGameSheet({
4757
4831
  return () => clearTimeout(timer);
4758
4832
  }
4759
4833
  }, [mutation.status, mutation.data]);
4760
- (0, import_react29.useEffect)(() => {
4834
+ (0, import_react30.useEffect)(() => {
4761
4835
  if (mutation.status === "error" && mutation.error) {
4762
4836
  onError?.(mutation.error);
4763
4837
  }
4764
4838
  }, [mutation.status, mutation.error]);
4765
- const handlePresetSelect = (0, import_react29.useCallback)((amount) => {
4839
+ const handlePresetSelect = (0, import_react30.useCallback)((amount) => {
4766
4840
  setSelectedAmount(amount);
4767
4841
  setIsCustom(false);
4768
4842
  setCustomAmount("");
4769
4843
  onAmountChange?.(amount);
4770
4844
  }, [onAmountChange]);
4771
- const handleCustomSelect = (0, import_react29.useCallback)(() => {
4845
+ const handleCustomSelect = (0, import_react30.useCallback)(() => {
4772
4846
  setIsCustom(true);
4773
4847
  setSelectedAmount(null);
4774
4848
  onAmountChange?.(null);
4775
4849
  }, [onAmountChange]);
4776
- const handleCustomAmountChange = (0, import_react29.useCallback)((text) => {
4850
+ const handleCustomAmountChange = (0, import_react30.useCallback)((text) => {
4777
4851
  const cleaned = text.replace(/[^0-9.]/g, "").replace(/(\..*?)\..*/g, "$1");
4778
4852
  setCustomAmount(cleaned);
4779
4853
  const parsed = parseFloat(cleaned);
@@ -4788,7 +4862,7 @@ function CreateCustomGameSheet({
4788
4862
  const winnerTakes = pot * (1 - fee / 100);
4789
4863
  const isMutating = mutation.status !== "idle" && mutation.status !== "success" && mutation.status !== "error";
4790
4864
  const canCreate = finalAmount !== null && finalAmount > 0 && !isMutating && mutation.status !== "success";
4791
- const handleCreate = (0, import_react29.useCallback)(async () => {
4865
+ const handleCreate = (0, import_react30.useCallback)(async () => {
4792
4866
  if (!finalAmount || !wallet.publicKey) return;
4793
4867
  try {
4794
4868
  await mutation.execute({
@@ -5057,7 +5131,7 @@ var styles11 = import_react_native17.StyleSheet.create({
5057
5131
  });
5058
5132
 
5059
5133
  // src/ui/game/JoinGameSheet.tsx
5060
- var import_react30 = require("react");
5134
+ var import_react31 = require("react");
5061
5135
  var import_react_native18 = require("react-native");
5062
5136
  var import_jsx_runtime15 = require("react/jsx-runtime");
5063
5137
  var STATUS_LABELS3 = {
@@ -5083,22 +5157,22 @@ function JoinGameSheet({
5083
5157
  const { wallet } = useDubs();
5084
5158
  const mutation = useJoinGame();
5085
5159
  const isCustomGame = game.gameMode === CUSTOM_GAME_MODE;
5086
- const [selectedTeam, setSelectedTeam] = (0, import_react30.useState)(null);
5087
- const overlayOpacity = (0, import_react30.useRef)(new import_react_native18.Animated.Value(0)).current;
5088
- (0, import_react30.useEffect)(() => {
5160
+ const [selectedTeam, setSelectedTeam] = (0, import_react31.useState)(null);
5161
+ const overlayOpacity = (0, import_react31.useRef)(new import_react_native18.Animated.Value(0)).current;
5162
+ (0, import_react31.useEffect)(() => {
5089
5163
  import_react_native18.Animated.timing(overlayOpacity, {
5090
5164
  toValue: visible ? 1 : 0,
5091
5165
  duration: 250,
5092
5166
  useNativeDriver: true
5093
5167
  }).start();
5094
5168
  }, [visible, overlayOpacity]);
5095
- (0, import_react30.useEffect)(() => {
5169
+ (0, import_react31.useEffect)(() => {
5096
5170
  if (visible) {
5097
5171
  setSelectedTeam(isPoolModeEnabled ? "home" : isCustomGame ? "away" : null);
5098
5172
  mutation.reset();
5099
5173
  }
5100
5174
  }, [visible]);
5101
- (0, import_react30.useEffect)(() => {
5175
+ (0, import_react31.useEffect)(() => {
5102
5176
  if (mutation.status === "success" && mutation.data) {
5103
5177
  onSuccess?.(mutation.data);
5104
5178
  const timer = setTimeout(() => {
@@ -5107,7 +5181,7 @@ function JoinGameSheet({
5107
5181
  return () => clearTimeout(timer);
5108
5182
  }
5109
5183
  }, [mutation.status, mutation.data]);
5110
- (0, import_react30.useEffect)(() => {
5184
+ (0, import_react31.useEffect)(() => {
5111
5185
  if (mutation.status === "error" && mutation.error) {
5112
5186
  onError?.(mutation.error);
5113
5187
  }
@@ -5118,7 +5192,7 @@ function JoinGameSheet({
5118
5192
  const homePool = game.homePool || 0;
5119
5193
  const awayPool = game.awayPool || 0;
5120
5194
  const buyIn = game.buyIn;
5121
- const { homeOdds, awayOdds, homeBets, awayBets } = (0, import_react30.useMemo)(() => ({
5195
+ const { homeOdds, awayOdds, homeBets, awayBets } = (0, import_react31.useMemo)(() => ({
5122
5196
  homeOdds: homePool > 0 ? (totalPool / homePool).toFixed(2) : "\u2014",
5123
5197
  awayOdds: awayPool > 0 ? (totalPool / awayPool).toFixed(2) : "\u2014",
5124
5198
  homeBets: bettors.filter((b) => b.team === "home").length,
@@ -5130,14 +5204,14 @@ function JoinGameSheet({
5130
5204
  const homeName = shortName ? shortName(opponents[0]?.name) : opponents[0]?.name || "Home";
5131
5205
  const awayName = shortName ? shortName(opponents[1]?.name) : opponents[1]?.name || "Away";
5132
5206
  const selectedName = selectedTeam === "home" ? homeName : selectedTeam === "away" ? awayName : "\u2014";
5133
- const alreadyJoined = (0, import_react30.useMemo)(() => {
5207
+ const alreadyJoined = (0, import_react31.useMemo)(() => {
5134
5208
  if (!wallet.publicKey) return false;
5135
5209
  const addr = wallet.publicKey.toBase58();
5136
5210
  return bettors.some((b) => b.wallet === addr);
5137
5211
  }, [bettors, wallet.publicKey]);
5138
5212
  const isMutating = mutation.status !== "idle" && mutation.status !== "success" && mutation.status !== "error";
5139
5213
  const canJoin = selectedTeam !== null && !isMutating && mutation.status !== "success" && !alreadyJoined;
5140
- const handleJoin = (0, import_react30.useCallback)(async () => {
5214
+ const handleJoin = (0, import_react31.useCallback)(async () => {
5141
5215
  if (!selectedTeam || !wallet.publicKey) return;
5142
5216
  try {
5143
5217
  await mutation.execute({
@@ -5281,7 +5355,7 @@ function TeamButton({
5281
5355
  ImageComponent,
5282
5356
  t
5283
5357
  }) {
5284
- const [imgFailed, setImgFailed] = (0, import_react30.useState)(false);
5358
+ const [imgFailed, setImgFailed] = (0, import_react31.useState)(false);
5285
5359
  const Img = ImageComponent || require("react-native").Image;
5286
5360
  const showImage = imageUrl && !imgFailed;
5287
5361
  return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
@@ -5458,7 +5532,7 @@ var styles12 = import_react_native18.StyleSheet.create({
5458
5532
  });
5459
5533
 
5460
5534
  // src/ui/game/ClaimPrizeSheet.tsx
5461
- var import_react31 = require("react");
5535
+ var import_react32 = require("react");
5462
5536
  var import_react_native19 = require("react-native");
5463
5537
  var import_jsx_runtime16 = require("react/jsx-runtime");
5464
5538
  var STATUS_LABELS4 = {
@@ -5479,18 +5553,18 @@ function ClaimPrizeSheet({
5479
5553
  const t = useDubsTheme();
5480
5554
  const { wallet } = useDubs();
5481
5555
  const mutation = useClaim();
5482
- const overlayOpacity = (0, import_react31.useRef)(new import_react_native19.Animated.Value(0)).current;
5483
- const celebrationScale = (0, import_react31.useRef)(new import_react_native19.Animated.Value(0)).current;
5484
- const celebrationOpacity = (0, import_react31.useRef)(new import_react_native19.Animated.Value(0)).current;
5485
- const [showCelebration, setShowCelebration] = (0, import_react31.useState)(false);
5486
- (0, import_react31.useEffect)(() => {
5556
+ const overlayOpacity = (0, import_react32.useRef)(new import_react_native19.Animated.Value(0)).current;
5557
+ const celebrationScale = (0, import_react32.useRef)(new import_react_native19.Animated.Value(0)).current;
5558
+ const celebrationOpacity = (0, import_react32.useRef)(new import_react_native19.Animated.Value(0)).current;
5559
+ const [showCelebration, setShowCelebration] = (0, import_react32.useState)(false);
5560
+ (0, import_react32.useEffect)(() => {
5487
5561
  import_react_native19.Animated.timing(overlayOpacity, {
5488
5562
  toValue: visible ? 1 : 0,
5489
5563
  duration: 250,
5490
5564
  useNativeDriver: true
5491
5565
  }).start();
5492
5566
  }, [visible, overlayOpacity]);
5493
- (0, import_react31.useEffect)(() => {
5567
+ (0, import_react32.useEffect)(() => {
5494
5568
  if (visible) {
5495
5569
  mutation.reset();
5496
5570
  setShowCelebration(false);
@@ -5498,7 +5572,7 @@ function ClaimPrizeSheet({
5498
5572
  celebrationOpacity.setValue(0);
5499
5573
  }
5500
5574
  }, [visible]);
5501
- (0, import_react31.useEffect)(() => {
5575
+ (0, import_react32.useEffect)(() => {
5502
5576
  if (mutation.status === "success" && mutation.data) {
5503
5577
  setShowCelebration(true);
5504
5578
  import_react_native19.Animated.parallel([
@@ -5521,14 +5595,14 @@ function ClaimPrizeSheet({
5521
5595
  return () => clearTimeout(timer);
5522
5596
  }
5523
5597
  }, [mutation.status, mutation.data]);
5524
- (0, import_react31.useEffect)(() => {
5598
+ (0, import_react32.useEffect)(() => {
5525
5599
  if (mutation.status === "error" && mutation.error) {
5526
5600
  onError?.(mutation.error);
5527
5601
  }
5528
5602
  }, [mutation.status, mutation.error]);
5529
5603
  const isMutating = mutation.status !== "idle" && mutation.status !== "success" && mutation.status !== "error";
5530
5604
  const canClaim = !isMutating && mutation.status !== "success" && !!wallet.publicKey;
5531
- const handleClaim = (0, import_react31.useCallback)(async () => {
5605
+ const handleClaim = (0, import_react32.useCallback)(async () => {
5532
5606
  if (!wallet.publicKey) return;
5533
5607
  try {
5534
5608
  await mutation.execute({
@@ -5761,7 +5835,7 @@ var styles13 = import_react_native19.StyleSheet.create({
5761
5835
  });
5762
5836
 
5763
5837
  // src/ui/game/ClaimButton.tsx
5764
- var import_react32 = require("react");
5838
+ var import_react33 = require("react");
5765
5839
  var import_react_native20 = require("react-native");
5766
5840
  var import_jsx_runtime17 = require("react/jsx-runtime");
5767
5841
  function ClaimButton({ gameId, style, onSuccess, onError }) {
@@ -5769,9 +5843,9 @@ function ClaimButton({ gameId, style, onSuccess, onError }) {
5769
5843
  const { wallet } = useDubs();
5770
5844
  const game = useGame(gameId);
5771
5845
  const claimStatus = useHasClaimed(gameId);
5772
- const [sheetVisible, setSheetVisible] = (0, import_react32.useState)(false);
5846
+ const [sheetVisible, setSheetVisible] = (0, import_react33.useState)(false);
5773
5847
  const walletAddress = wallet.publicKey?.toBase58() ?? null;
5774
- const myBet = (0, import_react32.useMemo)(() => {
5848
+ const myBet = (0, import_react33.useMemo)(() => {
5775
5849
  if (!walletAddress || !game.data?.bettors) return null;
5776
5850
  return game.data.bettors.find((b) => b.wallet === walletAddress) ?? null;
5777
5851
  }, [walletAddress, game.data?.bettors]);
@@ -5780,7 +5854,7 @@ function ClaimButton({ gameId, style, onSuccess, onError }) {
5780
5854
  const isWinner = isResolved && myBet != null && myBet.team === game.data?.winnerSide;
5781
5855
  const isEligible = myBet != null && isResolved && (isWinner || isRefund);
5782
5856
  const prizeAmount = isRefund ? myBet?.amount ?? 0 : game.data?.totalPool ?? 0;
5783
- const handleSuccess = (0, import_react32.useCallback)(
5857
+ const handleSuccess = (0, import_react33.useCallback)(
5784
5858
  (result) => {
5785
5859
  claimStatus.refetch();
5786
5860
  onSuccess?.(result);
@@ -5865,6 +5939,206 @@ var styles14 = import_react_native20.StyleSheet.create({
5865
5939
  fontWeight: "700"
5866
5940
  }
5867
5941
  });
5942
+
5943
+ // src/ui/game/EnterArcadePoolSheet.tsx
5944
+ var import_react34 = require("react");
5945
+ var import_react_native21 = require("react-native");
5946
+ var import_jsx_runtime18 = require("react/jsx-runtime");
5947
+ var STATUS_LABELS5 = {
5948
+ building: "Building transaction...",
5949
+ signing: "Approve in wallet...",
5950
+ confirming: "Confirming...",
5951
+ success: "Joined!"
5952
+ };
5953
+ function EnterArcadePoolSheet({
5954
+ visible,
5955
+ onDismiss,
5956
+ pool,
5957
+ stats,
5958
+ onSuccess,
5959
+ onError
5960
+ }) {
5961
+ const t = useDubsTheme();
5962
+ const { wallet } = useDubs();
5963
+ const mutation = useEnterArcadePool();
5964
+ const overlayOpacity = (0, import_react34.useRef)(new import_react_native21.Animated.Value(0)).current;
5965
+ (0, import_react34.useEffect)(() => {
5966
+ import_react_native21.Animated.timing(overlayOpacity, {
5967
+ toValue: visible ? 1 : 0,
5968
+ duration: 250,
5969
+ useNativeDriver: true
5970
+ }).start();
5971
+ }, [visible, overlayOpacity]);
5972
+ (0, import_react34.useEffect)(() => {
5973
+ if (visible) {
5974
+ mutation.reset();
5975
+ }
5976
+ }, [visible]);
5977
+ (0, import_react34.useEffect)(() => {
5978
+ if (mutation.status === "success" && mutation.data) {
5979
+ onSuccess?.(mutation.data);
5980
+ const timer = setTimeout(() => {
5981
+ onDismiss();
5982
+ }, 1500);
5983
+ return () => clearTimeout(timer);
5984
+ }
5985
+ }, [mutation.status, mutation.data]);
5986
+ (0, import_react34.useEffect)(() => {
5987
+ if (mutation.status === "error" && mutation.error) {
5988
+ onError?.(mutation.error);
5989
+ }
5990
+ }, [mutation.status, mutation.error]);
5991
+ const buyInSol = (pool.buy_in_lamports / 1e9).toFixed(4);
5992
+ const totalPlayers = stats?.total_entries ?? pool.total_entries ?? 0;
5993
+ const topScore = stats?.top_score ?? 0;
5994
+ const potSol = (pool.buy_in_lamports * Number(totalPlayers) / 1e9).toFixed(4);
5995
+ const isMutating = mutation.status !== "idle" && mutation.status !== "success" && mutation.status !== "error";
5996
+ const canJoin = !isMutating && mutation.status !== "success";
5997
+ const handleJoin = (0, import_react34.useCallback)(async () => {
5998
+ if (!wallet.publicKey) return;
5999
+ try {
6000
+ await mutation.execute(pool.id);
6001
+ } catch {
6002
+ }
6003
+ }, [wallet.publicKey, mutation.execute, pool.id]);
6004
+ const statusLabel = STATUS_LABELS5[mutation.status] || "";
6005
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
6006
+ import_react_native21.Modal,
6007
+ {
6008
+ visible,
6009
+ animationType: "slide",
6010
+ transparent: true,
6011
+ onRequestClose: onDismiss,
6012
+ children: [
6013
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.Animated.View, { style: [styles15.overlay, { opacity: overlayOpacity }], children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.TouchableOpacity, { style: styles15.overlayTap, activeOpacity: 1, onPress: onDismiss }) }),
6014
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
6015
+ import_react_native21.KeyboardAvoidingView,
6016
+ {
6017
+ style: styles15.keyboardView,
6018
+ behavior: import_react_native21.Platform.OS === "ios" ? "padding" : void 0,
6019
+ children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.View, { style: styles15.sheetPositioner, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native21.View, { style: [styles15.sheet, { backgroundColor: t.background }], children: [
6020
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.View, { style: styles15.handleRow, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.View, { style: [styles15.handle, { backgroundColor: t.textMuted }] }) }),
6021
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native21.View, { style: styles15.header, children: [
6022
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.Text, { style: [styles15.headerTitle, { color: t.text }], children: "Join Pool" }),
6023
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.TouchableOpacity, { onPress: onDismiss, activeOpacity: 0.8, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.Text, { style: [styles15.closeButton, { color: t.textMuted }], children: "\u2715" }) })
6024
+ ] }),
6025
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.Text, { style: [styles15.poolName, { color: t.textSecondary }], children: pool.name }),
6026
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native21.View, { style: [styles15.summaryCard, { backgroundColor: t.surface, borderColor: t.border }], children: [
6027
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native21.View, { style: styles15.summaryRow, children: [
6028
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.Text, { style: [styles15.summaryLabel, { color: t.textMuted }], children: "Buy-in" }),
6029
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native21.Text, { style: [styles15.summaryValue, { color: t.text }], children: [
6030
+ buyInSol,
6031
+ " SOL"
6032
+ ] })
6033
+ ] }),
6034
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.View, { style: [styles15.summarySep, { backgroundColor: t.border }] }),
6035
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native21.View, { style: styles15.summaryRow, children: [
6036
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.Text, { style: [styles15.summaryLabel, { color: t.textMuted }], children: "Players in" }),
6037
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.Text, { style: [styles15.summaryValue, { color: t.text }], children: totalPlayers })
6038
+ ] }),
6039
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.View, { style: [styles15.summarySep, { backgroundColor: t.border }] }),
6040
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native21.View, { style: styles15.summaryRow, children: [
6041
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.Text, { style: [styles15.summaryLabel, { color: t.textMuted }], children: "Current pot" }),
6042
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native21.Text, { style: [styles15.summaryValue, { color: t.success }], children: [
6043
+ potSol,
6044
+ " SOL"
6045
+ ] })
6046
+ ] }),
6047
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.View, { style: [styles15.summarySep, { backgroundColor: t.border }] }),
6048
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native21.View, { style: styles15.summaryRow, children: [
6049
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.Text, { style: [styles15.summaryLabel, { color: t.textMuted }], children: "Lives" }),
6050
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.Text, { style: [styles15.summaryValue, { color: t.text }], children: pool.max_lives })
6051
+ ] }),
6052
+ topScore > 0 && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
6053
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.View, { style: [styles15.summarySep, { backgroundColor: t.border }] }),
6054
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native21.View, { style: styles15.summaryRow, children: [
6055
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.Text, { style: [styles15.summaryLabel, { color: t.textMuted }], children: "Top score" }),
6056
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.Text, { style: [styles15.summaryValue, { color: t.text }], children: topScore })
6057
+ ] })
6058
+ ] })
6059
+ ] }),
6060
+ mutation.error && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.View, { style: [styles15.errorBox, { backgroundColor: t.errorBg, borderColor: t.errorBorder }], children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.Text, { style: [styles15.errorText, { color: t.errorText }], children: mutation.error.message }) }),
6061
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
6062
+ import_react_native21.TouchableOpacity,
6063
+ {
6064
+ style: [
6065
+ styles15.ctaButton,
6066
+ { backgroundColor: canJoin ? t.accent : t.border }
6067
+ ],
6068
+ disabled: !canJoin,
6069
+ onPress: handleJoin,
6070
+ activeOpacity: 0.8,
6071
+ children: isMutating ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native21.View, { style: styles15.ctaLoading, children: [
6072
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.ActivityIndicator, { size: "small", color: "#FFFFFF" }),
6073
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.Text, { style: styles15.ctaText, children: statusLabel })
6074
+ ] }) : mutation.status === "success" ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.Text, { style: styles15.ctaText, children: "Joined!" }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.Text, { style: [styles15.ctaText, !canJoin && { opacity: 0.5 }], children: `Join Pool \u2014 ${buyInSol} SOL` })
6075
+ }
6076
+ )
6077
+ ] }) })
6078
+ }
6079
+ )
6080
+ ]
6081
+ }
6082
+ );
6083
+ }
6084
+ var styles15 = import_react_native21.StyleSheet.create({
6085
+ overlay: {
6086
+ ...import_react_native21.StyleSheet.absoluteFillObject,
6087
+ backgroundColor: "rgba(0,0,0,0.5)"
6088
+ },
6089
+ overlayTap: { flex: 1 },
6090
+ keyboardView: { flex: 1, justifyContent: "flex-end" },
6091
+ sheetPositioner: { justifyContent: "flex-end" },
6092
+ sheet: {
6093
+ borderTopLeftRadius: 24,
6094
+ borderTopRightRadius: 24,
6095
+ paddingHorizontal: 20,
6096
+ paddingBottom: 40
6097
+ },
6098
+ handleRow: { alignItems: "center", paddingTop: 10, paddingBottom: 8 },
6099
+ handle: { width: 36, height: 4, borderRadius: 2, opacity: 0.4 },
6100
+ header: {
6101
+ flexDirection: "row",
6102
+ alignItems: "center",
6103
+ justifyContent: "space-between",
6104
+ paddingVertical: 12
6105
+ },
6106
+ headerTitle: { fontSize: 20, fontWeight: "700" },
6107
+ closeButton: { fontSize: 20, padding: 4 },
6108
+ poolName: { fontSize: 15, fontWeight: "600", marginBottom: 8 },
6109
+ summaryCard: {
6110
+ marginTop: 12,
6111
+ borderRadius: 16,
6112
+ borderWidth: 1,
6113
+ overflow: "hidden"
6114
+ },
6115
+ summaryRow: {
6116
+ flexDirection: "row",
6117
+ alignItems: "center",
6118
+ justifyContent: "space-between",
6119
+ paddingHorizontal: 16,
6120
+ paddingVertical: 14
6121
+ },
6122
+ summaryLabel: { fontSize: 14 },
6123
+ summaryValue: { fontSize: 15, fontWeight: "700" },
6124
+ summarySep: { height: 1, marginHorizontal: 16 },
6125
+ errorBox: {
6126
+ marginTop: 16,
6127
+ borderRadius: 12,
6128
+ borderWidth: 1,
6129
+ padding: 12
6130
+ },
6131
+ errorText: { fontSize: 13, fontWeight: "500" },
6132
+ ctaButton: {
6133
+ marginTop: 20,
6134
+ height: 56,
6135
+ borderRadius: 14,
6136
+ justifyContent: "center",
6137
+ alignItems: "center"
6138
+ },
6139
+ ctaText: { color: "#FFFFFF", fontSize: 16, fontWeight: "700" },
6140
+ ctaLoading: { flexDirection: "row", alignItems: "center", gap: 10 }
6141
+ });
5868
6142
  // Annotate the CommonJS export names for ESM import in node:
5869
6143
  0 && (module.exports = {
5870
6144
  AuthGate,
@@ -5877,6 +6151,7 @@ var styles14 = import_react_native20.StyleSheet.create({
5877
6151
  DubsApiError,
5878
6152
  DubsClient,
5879
6153
  DubsProvider,
6154
+ EnterArcadePoolSheet,
5880
6155
  GamePoster,
5881
6156
  JoinGameButton,
5882
6157
  JoinGameSheet,
@@ -5908,6 +6183,7 @@ var styles14 = import_react_native20.StyleSheet.create({
5908
6183
  useCreateGame,
5909
6184
  useDubs,
5910
6185
  useDubsTheme,
6186
+ useEnterArcadePool,
5911
6187
  useEvents,
5912
6188
  useGame,
5913
6189
  useGames,