@dubsdotapp/expo 0.3.9 → 0.4.0

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
@@ -64,6 +64,7 @@ __export(index_exports, {
64
64
  parseSolanaError: () => parseSolanaError,
65
65
  signAndSendBase64Transaction: () => signAndSendBase64Transaction,
66
66
  useAppConfig: () => useAppConfig,
67
+ useArcadeBridge: () => useArcadeBridge,
67
68
  useArcadeCountdown: () => useArcadeCountdown,
68
69
  useArcadeGame: () => useArcadeGame,
69
70
  useArcadePool: () => useArcadePool,
@@ -718,7 +719,7 @@ function createSecureStoreStorage() {
718
719
  }
719
720
 
720
721
  // src/provider.tsx
721
- var import_react23 = require("react");
722
+ var import_react24 = require("react");
722
723
 
723
724
  // src/ui/theme.ts
724
725
  var import_react = require("react");
@@ -1776,7 +1777,7 @@ function ManagedWalletProvider({
1776
1777
  }
1777
1778
 
1778
1779
  // src/ui/AuthGate.tsx
1779
- var import_react22 = __toESM(require("react"));
1780
+ var import_react23 = __toESM(require("react"));
1780
1781
  var import_react_native8 = require("react-native");
1781
1782
 
1782
1783
  // src/hooks/useEvents.ts
@@ -2842,6 +2843,91 @@ function useArcadeCountdown(nextResolution) {
2842
2843
  };
2843
2844
  }
2844
2845
 
2846
+ // src/hooks/useArcadeBridge.ts
2847
+ var import_react22 = require("react");
2848
+ var PROTOCOL_VERSION = "1.0";
2849
+ function useArcadeBridge({
2850
+ canPlay,
2851
+ startAttempt,
2852
+ submitScore,
2853
+ onScoreSubmitted,
2854
+ onError
2855
+ }) {
2856
+ const webviewRef = (0, import_react22.useRef)(null);
2857
+ const sessionTokenRef = (0, import_react22.useRef)(null);
2858
+ const gameStartTimeRef = (0, import_react22.useRef)(0);
2859
+ const [lastResult, setLastResult] = (0, import_react22.useState)(null);
2860
+ const [bridgeLoading, setBridgeLoading] = (0, import_react22.useState)(false);
2861
+ const injectSession = (0, import_react22.useCallback)((token, attemptNumber) => {
2862
+ webviewRef.current?.injectJavaScript(`
2863
+ window.ARCADE_SESSION_TOKEN = ${JSON.stringify(token)};
2864
+ window.ARCADE_ATTEMPT_NUMBER = ${attemptNumber};
2865
+ window._ARCADE_GAME_START_TIME = Date.now();
2866
+ window.dispatchEvent(new Event('ARCADE_START'));
2867
+ true;
2868
+ `);
2869
+ }, []);
2870
+ const triggerPlay = (0, import_react22.useCallback)(async () => {
2871
+ if (!canPlay) return;
2872
+ setBridgeLoading(true);
2873
+ try {
2874
+ const result = await startAttempt();
2875
+ sessionTokenRef.current = result.sessionToken;
2876
+ gameStartTimeRef.current = Date.now();
2877
+ setLastResult(null);
2878
+ injectSession(result.sessionToken, result.attemptNumber);
2879
+ } catch (err) {
2880
+ const e = err instanceof Error ? err : new Error(String(err));
2881
+ onError?.(e);
2882
+ } finally {
2883
+ setBridgeLoading(false);
2884
+ }
2885
+ }, [canPlay, startAttempt, injectSession, onError]);
2886
+ const handleMessage = (0, import_react22.useCallback)(
2887
+ async (event) => {
2888
+ let data;
2889
+ try {
2890
+ data = JSON.parse(event.nativeEvent.data);
2891
+ } catch {
2892
+ return;
2893
+ }
2894
+ if (data.dubsArcade !== PROTOCOL_VERSION) return;
2895
+ switch (data.type) {
2896
+ case "TAP_PLAY": {
2897
+ if (canPlay) {
2898
+ triggerPlay();
2899
+ }
2900
+ return;
2901
+ }
2902
+ case "GAME_OVER": {
2903
+ const token = sessionTokenRef.current;
2904
+ if (!token) return;
2905
+ const score = typeof data.score === "number" ? data.score : 0;
2906
+ const duration = gameStartTimeRef.current > 0 ? Date.now() - gameStartTimeRef.current : typeof data.durationMs === "number" ? data.durationMs : void 0;
2907
+ sessionTokenRef.current = null;
2908
+ gameStartTimeRef.current = 0;
2909
+ setBridgeLoading(true);
2910
+ try {
2911
+ const result = await submitScore(token, score, duration);
2912
+ setLastResult(result);
2913
+ onScoreSubmitted?.(result);
2914
+ } catch (err) {
2915
+ const e = err instanceof Error ? err : new Error(String(err));
2916
+ onError?.(e);
2917
+ } finally {
2918
+ setBridgeLoading(false);
2919
+ }
2920
+ return;
2921
+ }
2922
+ default:
2923
+ return;
2924
+ }
2925
+ },
2926
+ [canPlay, triggerPlay, submitScore, onScoreSubmitted, onError]
2927
+ );
2928
+ return { webviewRef, handleMessage, triggerPlay, lastResult, bridgeLoading };
2929
+ }
2930
+
2845
2931
  // src/ui/AvatarEditor.tsx
2846
2932
  var import_react_native7 = require("react-native");
2847
2933
  var import_jsx_runtime3 = require("react/jsx-runtime");
@@ -3002,11 +3088,11 @@ function AuthGate({
3002
3088
  }) {
3003
3089
  const { client, pushEnabled } = useDubs();
3004
3090
  const auth = useAuth();
3005
- const [phase, setPhase] = (0, import_react22.useState)("init");
3006
- const [registrationPhase, setRegistrationPhase] = (0, import_react22.useState)(false);
3007
- const [showPushSetup, setShowPushSetup] = (0, import_react22.useState)(false);
3008
- const [isRestoredSession, setIsRestoredSession] = (0, import_react22.useState)(false);
3009
- (0, import_react22.useEffect)(() => {
3091
+ const [phase, setPhase] = (0, import_react23.useState)("init");
3092
+ const [registrationPhase, setRegistrationPhase] = (0, import_react23.useState)(false);
3093
+ const [showPushSetup, setShowPushSetup] = (0, import_react23.useState)(false);
3094
+ const [isRestoredSession, setIsRestoredSession] = (0, import_react23.useState)(false);
3095
+ (0, import_react23.useEffect)(() => {
3010
3096
  let cancelled = false;
3011
3097
  (async () => {
3012
3098
  try {
@@ -3033,23 +3119,23 @@ function AuthGate({
3033
3119
  cancelled = true;
3034
3120
  };
3035
3121
  }, []);
3036
- (0, import_react22.useEffect)(() => {
3122
+ (0, import_react23.useEffect)(() => {
3037
3123
  if (auth.status === "needsRegistration") setRegistrationPhase(true);
3038
3124
  }, [auth.status]);
3039
- (0, import_react22.useEffect)(() => {
3125
+ (0, import_react23.useEffect)(() => {
3040
3126
  if (pushEnabled && auth.status === "authenticated" && registrationPhase && !isRestoredSession) {
3041
3127
  setShowPushSetup(true);
3042
3128
  }
3043
3129
  }, [pushEnabled, auth.status, registrationPhase, isRestoredSession]);
3044
- (0, import_react22.useEffect)(() => {
3130
+ (0, import_react23.useEffect)(() => {
3045
3131
  if (auth.token) onSaveToken(auth.token);
3046
3132
  }, [auth.token]);
3047
- const retry = (0, import_react22.useCallback)(() => {
3133
+ const retry = (0, import_react23.useCallback)(() => {
3048
3134
  setRegistrationPhase(false);
3049
3135
  auth.reset();
3050
3136
  auth.authenticate();
3051
3137
  }, [auth]);
3052
- const handleRegister = (0, import_react22.useCallback)(
3138
+ const handleRegister = (0, import_react23.useCallback)(
3053
3139
  (username, referralCode, avatarUrl) => {
3054
3140
  auth.register(username, referralCode, avatarUrl);
3055
3141
  },
@@ -3141,7 +3227,7 @@ function DefaultErrorScreen({ error, onRetry, appName, accentColor }) {
3141
3227
  function StepIndicator({ currentStep }) {
3142
3228
  const t = useDubsTheme();
3143
3229
  const steps = [0, 1, 2, 3];
3144
- 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_react22.default.Fragment, { children: [
3230
+ 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_react23.default.Fragment, { children: [
3145
3231
  i > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native8.View, { style: [s.stepLine, { backgroundColor: i <= currentStep ? t.success : t.border }] }),
3146
3232
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3147
3233
  import_react_native8.View,
@@ -3165,20 +3251,20 @@ function DefaultRegistrationScreen({
3165
3251
  }) {
3166
3252
  const t = useDubsTheme();
3167
3253
  const accent = accentColor || t.accent;
3168
- const [step, setStep] = (0, import_react22.useState)(0);
3169
- const [avatarSeed, setAvatarSeed] = (0, import_react22.useState)(generateSeed);
3170
- const [avatarStyle, setAvatarStyle] = (0, import_react22.useState)("adventurer");
3171
- const [avatarBg, setAvatarBg] = (0, import_react22.useState)("1a1a2e");
3172
- const [showStyles, setShowStyles] = (0, import_react22.useState)(false);
3173
- const [username, setUsername] = (0, import_react22.useState)("");
3174
- const [referralCode, setReferralCode] = (0, import_react22.useState)("");
3175
- const [checking, setChecking] = (0, import_react22.useState)(false);
3176
- const [availability, setAvailability] = (0, import_react22.useState)(null);
3177
- const debounceRef = (0, import_react22.useRef)(null);
3178
- const fadeAnim = (0, import_react22.useRef)(new import_react_native8.Animated.Value(1)).current;
3179
- const slideAnim = (0, import_react22.useRef)(new import_react_native8.Animated.Value(0)).current;
3254
+ const [step, setStep] = (0, import_react23.useState)(0);
3255
+ const [avatarSeed, setAvatarSeed] = (0, import_react23.useState)(generateSeed);
3256
+ const [avatarStyle, setAvatarStyle] = (0, import_react23.useState)("adventurer");
3257
+ const [avatarBg, setAvatarBg] = (0, import_react23.useState)("1a1a2e");
3258
+ const [showStyles, setShowStyles] = (0, import_react23.useState)(false);
3259
+ const [username, setUsername] = (0, import_react23.useState)("");
3260
+ const [referralCode, setReferralCode] = (0, import_react23.useState)("");
3261
+ const [checking, setChecking] = (0, import_react23.useState)(false);
3262
+ const [availability, setAvailability] = (0, import_react23.useState)(null);
3263
+ const debounceRef = (0, import_react23.useRef)(null);
3264
+ const fadeAnim = (0, import_react23.useRef)(new import_react_native8.Animated.Value(1)).current;
3265
+ const slideAnim = (0, import_react23.useRef)(new import_react_native8.Animated.Value(0)).current;
3180
3266
  const avatarUrl = getAvatarUrl(avatarStyle, avatarSeed, avatarBg);
3181
- (0, import_react22.useEffect)(() => {
3267
+ (0, import_react23.useEffect)(() => {
3182
3268
  if (debounceRef.current) clearTimeout(debounceRef.current);
3183
3269
  const trimmed = username.trim();
3184
3270
  if (trimmed.length < 3) {
@@ -3201,7 +3287,7 @@ function DefaultRegistrationScreen({
3201
3287
  if (debounceRef.current) clearTimeout(debounceRef.current);
3202
3288
  };
3203
3289
  }, [username, client]);
3204
- const animateToStep = (0, import_react22.useCallback)((newStep) => {
3290
+ const animateToStep = (0, import_react23.useCallback)((newStep) => {
3205
3291
  const dir = newStep > step ? 1 : -1;
3206
3292
  import_react_native8.Keyboard.dismiss();
3207
3293
  import_react_native8.Animated.parallel([
@@ -3440,8 +3526,8 @@ function DefaultRegistrationScreen({
3440
3526
  }
3441
3527
  function PushTokenRestorer() {
3442
3528
  const push = usePushNotifications();
3443
- const restored = (0, import_react22.useRef)(false);
3444
- (0, import_react22.useEffect)(() => {
3529
+ const restored = (0, import_react23.useRef)(false);
3530
+ (0, import_react23.useEffect)(() => {
3445
3531
  if (restored.current) return;
3446
3532
  restored.current = true;
3447
3533
  push.restoreIfGranted();
@@ -3456,9 +3542,9 @@ function PushSetupScreen({
3456
3542
  const t = useDubsTheme();
3457
3543
  const accent = accentColor || t.accent;
3458
3544
  const push = usePushNotifications();
3459
- const fadeAnim = (0, import_react22.useRef)(new import_react_native8.Animated.Value(0)).current;
3460
- const slideAnim = (0, import_react22.useRef)(new import_react_native8.Animated.Value(30)).current;
3461
- (0, import_react22.useEffect)(() => {
3545
+ const fadeAnim = (0, import_react23.useRef)(new import_react_native8.Animated.Value(0)).current;
3546
+ const slideAnim = (0, import_react23.useRef)(new import_react_native8.Animated.Value(30)).current;
3547
+ (0, import_react23.useEffect)(() => {
3462
3548
  import_react_native8.Animated.parallel([
3463
3549
  import_react_native8.Animated.timing(fadeAnim, { toValue: 1, duration: 300, useNativeDriver: true }),
3464
3550
  import_react_native8.Animated.timing(slideAnim, { toValue: 0, duration: 300, useNativeDriver: true })
@@ -3594,7 +3680,7 @@ var s = import_react_native8.StyleSheet.create({
3594
3680
 
3595
3681
  // src/provider.tsx
3596
3682
  var import_jsx_runtime5 = require("react/jsx-runtime");
3597
- var DubsContext = (0, import_react23.createContext)(null);
3683
+ var DubsContext = (0, import_react24.createContext)(null);
3598
3684
  function DubsProvider({
3599
3685
  apiKey,
3600
3686
  children,
@@ -3616,11 +3702,11 @@ function DubsProvider({
3616
3702
  const config = NETWORK_CONFIG[network];
3617
3703
  const baseUrl = baseUrlOverride || config.baseUrl;
3618
3704
  const rpcUrl = rpcUrlOverride || config.rpcUrl;
3619
- const client = (0, import_react23.useMemo)(() => new DubsClient({ apiKey, baseUrl }), [apiKey, baseUrl]);
3620
- const storage = (0, import_react23.useMemo)(() => tokenStorage || createSecureStoreStorage(), [tokenStorage]);
3621
- const [uiConfig, setUiConfig] = (0, import_react23.useState)(null);
3622
- const [resolvedNetwork, setResolvedNetwork] = (0, import_react23.useState)(network);
3623
- (0, import_react23.useEffect)(() => {
3705
+ const client = (0, import_react24.useMemo)(() => new DubsClient({ apiKey, baseUrl }), [apiKey, baseUrl]);
3706
+ const storage = (0, import_react24.useMemo)(() => tokenStorage || createSecureStoreStorage(), [tokenStorage]);
3707
+ const [uiConfig, setUiConfig] = (0, import_react24.useState)(null);
3708
+ const [resolvedNetwork, setResolvedNetwork] = (0, import_react24.useState)(network);
3709
+ (0, import_react24.useEffect)(() => {
3624
3710
  client.getAppConfig().then((cfg) => {
3625
3711
  console.log("[DubsProvider] UI config loaded:", JSON.stringify(cfg));
3626
3712
  setUiConfig(cfg);
@@ -3636,7 +3722,7 @@ function DubsProvider({
3636
3722
  const resolvedConfig = NETWORK_CONFIG[resolvedNetwork];
3637
3723
  const resolvedRpcUrl = rpcUrlOverride || resolvedConfig.rpcUrl;
3638
3724
  const cluster = resolvedConfig.cluster;
3639
- const connection = (0, import_react23.useMemo)(() => new import_web34.Connection(resolvedRpcUrl, { commitment: "confirmed" }), [resolvedRpcUrl]);
3725
+ const connection = (0, import_react24.useMemo)(() => new import_web34.Connection(resolvedRpcUrl, { commitment: "confirmed" }), [resolvedRpcUrl]);
3640
3726
  if (uiConfig === null) return null;
3641
3727
  const themeOverrides = {};
3642
3728
  if (uiConfig.accentColor) {
@@ -3712,11 +3798,11 @@ function ManagedInner({
3712
3798
  children
3713
3799
  }) {
3714
3800
  const managedDisconnect = useDisconnect();
3715
- const disconnect = (0, import_react23.useCallback)(async () => {
3801
+ const disconnect = (0, import_react24.useCallback)(async () => {
3716
3802
  client.setToken(null);
3717
3803
  await managedDisconnect?.();
3718
3804
  }, [client, managedDisconnect]);
3719
- const value = (0, import_react23.useMemo)(
3805
+ const value = (0, import_react24.useMemo)(
3720
3806
  () => ({ client, wallet, connection, appName, network, disconnect, uiConfig, pushEnabled }),
3721
3807
  [client, wallet, connection, appName, network, disconnect, uiConfig, pushEnabled]
3722
3808
  );
@@ -3753,13 +3839,13 @@ function ExternalWalletProvider({
3753
3839
  pushEnabled,
3754
3840
  children
3755
3841
  }) {
3756
- const disconnect = (0, import_react23.useCallback)(async () => {
3842
+ const disconnect = (0, import_react24.useCallback)(async () => {
3757
3843
  client.setToken(null);
3758
3844
  await storage.deleteItem(STORAGE_KEYS.JWT_TOKEN).catch(() => {
3759
3845
  });
3760
3846
  await wallet.disconnect?.();
3761
3847
  }, [client, storage, wallet]);
3762
- const value = (0, import_react23.useMemo)(
3848
+ const value = (0, import_react24.useMemo)(
3763
3849
  () => ({ client, wallet, connection, appName, network, disconnect, uiConfig, pushEnabled }),
3764
3850
  [client, wallet, connection, appName, network, disconnect, uiConfig, pushEnabled]
3765
3851
  );
@@ -3784,19 +3870,19 @@ function ExternalWalletProvider({
3784
3870
  ) });
3785
3871
  }
3786
3872
  function useDubs() {
3787
- const ctx = (0, import_react23.useContext)(DubsContext);
3873
+ const ctx = (0, import_react24.useContext)(DubsContext);
3788
3874
  if (!ctx) {
3789
3875
  throw new Error("useDubs must be used within a <DubsProvider>");
3790
3876
  }
3791
3877
  return ctx;
3792
3878
  }
3793
3879
  function useAppConfig() {
3794
- const ctx = (0, import_react23.useContext)(DubsContext);
3880
+ const ctx = (0, import_react24.useContext)(DubsContext);
3795
3881
  return ctx?.uiConfig || {};
3796
3882
  }
3797
3883
 
3798
3884
  // src/ui/UserProfileCard.tsx
3799
- var import_react24 = require("react");
3885
+ var import_react25 = require("react");
3800
3886
  var import_react_native9 = require("react-native");
3801
3887
  var import_jsx_runtime6 = require("react/jsx-runtime");
3802
3888
  function truncateAddress(address, chars = 4) {
@@ -3816,7 +3902,7 @@ function UserProfileCard({
3816
3902
  memberSince
3817
3903
  }) {
3818
3904
  const t = useDubsTheme();
3819
- const imageUri = (0, import_react24.useMemo)(
3905
+ const imageUri = (0, import_react25.useMemo)(
3820
3906
  () => ensurePngAvatar(avatarUrl) || `https://api.dicebear.com/9.x/avataaars/png?seed=${walletAddress}&size=128`,
3821
3907
  [avatarUrl, walletAddress]
3822
3908
  );
@@ -4009,7 +4095,7 @@ var styles4 = import_react_native10.StyleSheet.create({
4009
4095
  });
4010
4096
 
4011
4097
  // src/ui/UserProfileSheet.tsx
4012
- var import_react25 = require("react");
4098
+ var import_react26 = require("react");
4013
4099
  var import_react_native11 = require("react-native");
4014
4100
  var import_jsx_runtime8 = require("react/jsx-runtime");
4015
4101
  function truncateAddress3(address, chars = 4) {
@@ -4027,31 +4113,31 @@ function UserProfileSheet({
4027
4113
  const { client } = useDubs();
4028
4114
  const { refreshUser } = useAuth();
4029
4115
  const push = usePushNotifications();
4030
- const overlayOpacity = (0, import_react25.useRef)(new import_react_native11.Animated.Value(0)).current;
4031
- const parsed = (0, import_react25.useMemo)(() => parseAvatarUrl(user.avatar), [user.avatar]);
4032
- const [avatarStyle, setAvatarStyle] = (0, import_react25.useState)(parsed.style);
4033
- const [avatarSeed, setAvatarSeed] = (0, import_react25.useState)(parsed.seed);
4034
- const [bgColor, setBgColor] = (0, import_react25.useState)(parsed.bg);
4035
- const [saving, setSaving] = (0, import_react25.useState)(false);
4036
- const [error, setError] = (0, import_react25.useState)(null);
4037
- (0, import_react25.useEffect)(() => {
4116
+ const overlayOpacity = (0, import_react26.useRef)(new import_react_native11.Animated.Value(0)).current;
4117
+ const parsed = (0, import_react26.useMemo)(() => parseAvatarUrl(user.avatar), [user.avatar]);
4118
+ const [avatarStyle, setAvatarStyle] = (0, import_react26.useState)(parsed.style);
4119
+ const [avatarSeed, setAvatarSeed] = (0, import_react26.useState)(parsed.seed);
4120
+ const [bgColor, setBgColor] = (0, import_react26.useState)(parsed.bg);
4121
+ const [saving, setSaving] = (0, import_react26.useState)(false);
4122
+ const [error, setError] = (0, import_react26.useState)(null);
4123
+ (0, import_react26.useEffect)(() => {
4038
4124
  const p = parseAvatarUrl(user.avatar);
4039
4125
  setAvatarStyle(p.style);
4040
4126
  setAvatarSeed(p.seed);
4041
4127
  setBgColor(p.bg);
4042
4128
  }, [user.avatar]);
4043
- (0, import_react25.useEffect)(() => {
4129
+ (0, import_react26.useEffect)(() => {
4044
4130
  import_react_native11.Animated.timing(overlayOpacity, {
4045
4131
  toValue: visible ? 1 : 0,
4046
4132
  duration: 250,
4047
4133
  useNativeDriver: true
4048
4134
  }).start();
4049
4135
  }, [visible, overlayOpacity]);
4050
- (0, import_react25.useEffect)(() => {
4136
+ (0, import_react26.useEffect)(() => {
4051
4137
  if (visible) setError(null);
4052
4138
  }, [visible]);
4053
4139
  const currentAvatarUrl = getAvatarUrl(avatarStyle, avatarSeed, bgColor);
4054
- const saveAvatar = (0, import_react25.useCallback)(async (newUrl) => {
4140
+ const saveAvatar = (0, import_react26.useCallback)(async (newUrl) => {
4055
4141
  setSaving(true);
4056
4142
  setError(null);
4057
4143
  try {
@@ -4064,16 +4150,16 @@ function UserProfileSheet({
4064
4150
  setSaving(false);
4065
4151
  }
4066
4152
  }, [client, refreshUser, onAvatarUpdated]);
4067
- const handleStyleChange = (0, import_react25.useCallback)((style) => {
4153
+ const handleStyleChange = (0, import_react26.useCallback)((style) => {
4068
4154
  setAvatarStyle(style);
4069
4155
  saveAvatar(getAvatarUrl(style, avatarSeed, bgColor));
4070
4156
  }, [avatarSeed, bgColor, saveAvatar]);
4071
- const handleShuffle = (0, import_react25.useCallback)(() => {
4157
+ const handleShuffle = (0, import_react26.useCallback)(() => {
4072
4158
  const newSeed = generateSeed();
4073
4159
  setAvatarSeed(newSeed);
4074
4160
  saveAvatar(getAvatarUrl(avatarStyle, newSeed, bgColor));
4075
4161
  }, [avatarStyle, bgColor, saveAvatar]);
4076
- const handleBgChange = (0, import_react25.useCallback)((color) => {
4162
+ const handleBgChange = (0, import_react26.useCallback)((color) => {
4077
4163
  setBgColor(color);
4078
4164
  saveAvatar(getAvatarUrl(avatarStyle, avatarSeed, color));
4079
4165
  }, [avatarStyle, avatarSeed, saveAvatar]);
@@ -4353,7 +4439,7 @@ var styles5 = import_react_native11.StyleSheet.create({
4353
4439
  });
4354
4440
 
4355
4441
  // src/ui/game/GamePoster.tsx
4356
- var import_react26 = require("react");
4442
+ var import_react27 = require("react");
4357
4443
  var import_react_native12 = require("react-native");
4358
4444
  var import_jsx_runtime9 = require("react/jsx-runtime");
4359
4445
  function computeCountdown(lockTimestamp) {
@@ -4403,7 +4489,7 @@ function GamePoster({ game, ImageComponent }) {
4403
4489
  ] });
4404
4490
  }
4405
4491
  function TeamLogoInternal({ url, size, Img }) {
4406
- const [failed, setFailed] = (0, import_react26.useState)(false);
4492
+ const [failed, setFailed] = (0, import_react27.useState)(false);
4407
4493
  if (!url || failed) {
4408
4494
  return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native12.View, { style: [styles6.logoPlaceholder, { width: size, height: size, borderRadius: size / 2 }] });
4409
4495
  }
@@ -4504,7 +4590,7 @@ var styles6 = import_react_native12.StyleSheet.create({
4504
4590
  });
4505
4591
 
4506
4592
  // src/ui/game/LivePoolsCard.tsx
4507
- var import_react27 = require("react");
4593
+ var import_react28 = require("react");
4508
4594
  var import_react_native13 = require("react-native");
4509
4595
  var import_jsx_runtime10 = require("react/jsx-runtime");
4510
4596
  function LivePoolsCard({
@@ -4520,7 +4606,7 @@ function LivePoolsCard({
4520
4606
  const homePool = game.homePool || 0;
4521
4607
  const awayPool = game.awayPool || 0;
4522
4608
  const totalPool = game.totalPool || 0;
4523
- const { homePercent, awayPercent, homeOdds, awayOdds } = (0, import_react27.useMemo)(() => {
4609
+ const { homePercent, awayPercent, homeOdds, awayOdds } = (0, import_react28.useMemo)(() => {
4524
4610
  return {
4525
4611
  homePercent: totalPool > 0 ? homePool / totalPool * 100 : 50,
4526
4612
  awayPercent: totalPool > 0 ? awayPool / totalPool * 100 : 50,
@@ -4583,7 +4669,7 @@ var styles7 = import_react_native13.StyleSheet.create({
4583
4669
  });
4584
4670
 
4585
4671
  // src/ui/game/PickWinnerCard.tsx
4586
- var import_react28 = require("react");
4672
+ var import_react29 = require("react");
4587
4673
  var import_react_native14 = require("react-native");
4588
4674
  var import_jsx_runtime11 = require("react/jsx-runtime");
4589
4675
  function PickWinnerCard({
@@ -4601,7 +4687,7 @@ function PickWinnerCard({
4601
4687
  const totalPool = game.totalPool || 0;
4602
4688
  const homePool = game.homePool || 0;
4603
4689
  const awayPool = game.awayPool || 0;
4604
- const { homeOdds, awayOdds, homeBets, awayBets } = (0, import_react28.useMemo)(() => ({
4690
+ const { homeOdds, awayOdds, homeBets, awayBets } = (0, import_react29.useMemo)(() => ({
4605
4691
  homeOdds: homePool > 0 ? (totalPool / homePool).toFixed(2) : "\u2014",
4606
4692
  awayOdds: awayPool > 0 ? (totalPool / awayPool).toFixed(2) : "\u2014",
4607
4693
  homeBets: bettors.filter((b) => b.team === "home").length,
@@ -4654,7 +4740,7 @@ function TeamOption({
4654
4740
  ImageComponent,
4655
4741
  t
4656
4742
  }) {
4657
- const [imgFailed, setImgFailed] = (0, import_react28.useState)(false);
4743
+ const [imgFailed, setImgFailed] = (0, import_react29.useState)(false);
4658
4744
  const Img = ImageComponent || require("react-native").Image;
4659
4745
  const showImage = imageUrl && !imgFailed;
4660
4746
  return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
@@ -4695,7 +4781,7 @@ var styles8 = import_react_native14.StyleSheet.create({
4695
4781
  });
4696
4782
 
4697
4783
  // src/ui/game/PlayersCard.tsx
4698
- var import_react29 = require("react");
4784
+ var import_react30 = require("react");
4699
4785
  var import_react_native15 = require("react-native");
4700
4786
  var import_jsx_runtime12 = require("react/jsx-runtime");
4701
4787
  function truncateWallet(addr, chars) {
@@ -4744,7 +4830,7 @@ function BettorRow({
4744
4830
  ImageComponent,
4745
4831
  t
4746
4832
  }) {
4747
- const [imgFailed, setImgFailed] = (0, import_react29.useState)(false);
4833
+ const [imgFailed, setImgFailed] = (0, import_react30.useState)(false);
4748
4834
  const Img = ImageComponent || require("react-native").Image;
4749
4835
  const showAvatar = bettor.avatar && !imgFailed;
4750
4836
  return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native15.View, { style: [styles9.row, !isFirst && { borderTopColor: t.border, borderTopWidth: 1 }], children: [
@@ -4771,7 +4857,7 @@ var styles9 = import_react_native15.StyleSheet.create({
4771
4857
  });
4772
4858
 
4773
4859
  // src/ui/game/JoinGameButton.tsx
4774
- var import_react30 = require("react");
4860
+ var import_react31 = require("react");
4775
4861
  var import_react_native16 = require("react-native");
4776
4862
  var import_jsx_runtime13 = require("react/jsx-runtime");
4777
4863
  var STATUS_LABELS = {
@@ -4782,7 +4868,7 @@ var STATUS_LABELS = {
4782
4868
  };
4783
4869
  function JoinGameButton({ game, walletAddress, selectedTeam, status, onJoin }) {
4784
4870
  const t = useDubsTheme();
4785
- const alreadyJoined = (0, import_react30.useMemo)(() => {
4871
+ const alreadyJoined = (0, import_react31.useMemo)(() => {
4786
4872
  if (!walletAddress) return false;
4787
4873
  return (game.bettors || []).some((b) => b.wallet === walletAddress);
4788
4874
  }, [game.bettors, walletAddress]);
@@ -4823,7 +4909,7 @@ var styles10 = import_react_native16.StyleSheet.create({
4823
4909
  });
4824
4910
 
4825
4911
  // src/ui/game/CreateCustomGameSheet.tsx
4826
- var import_react31 = require("react");
4912
+ var import_react32 = require("react");
4827
4913
  var import_react_native17 = require("react-native");
4828
4914
  var import_jsx_runtime14 = require("react/jsx-runtime");
4829
4915
  var STATUS_LABELS2 = {
@@ -4849,18 +4935,18 @@ function CreateCustomGameSheet({
4849
4935
  const t = useDubsTheme();
4850
4936
  const { wallet } = useDubs();
4851
4937
  const mutation = useCreateCustomGame();
4852
- const [selectedAmount, setSelectedAmount] = (0, import_react31.useState)(null);
4853
- const [customAmount, setCustomAmount] = (0, import_react31.useState)("");
4854
- const [isCustom, setIsCustom] = (0, import_react31.useState)(false);
4855
- const overlayOpacity = (0, import_react31.useRef)(new import_react_native17.Animated.Value(0)).current;
4856
- (0, import_react31.useEffect)(() => {
4938
+ const [selectedAmount, setSelectedAmount] = (0, import_react32.useState)(null);
4939
+ const [customAmount, setCustomAmount] = (0, import_react32.useState)("");
4940
+ const [isCustom, setIsCustom] = (0, import_react32.useState)(false);
4941
+ const overlayOpacity = (0, import_react32.useRef)(new import_react_native17.Animated.Value(0)).current;
4942
+ (0, import_react32.useEffect)(() => {
4857
4943
  import_react_native17.Animated.timing(overlayOpacity, {
4858
4944
  toValue: visible ? 1 : 0,
4859
4945
  duration: 250,
4860
4946
  useNativeDriver: true
4861
4947
  }).start();
4862
4948
  }, [visible, overlayOpacity]);
4863
- (0, import_react31.useEffect)(() => {
4949
+ (0, import_react32.useEffect)(() => {
4864
4950
  if (visible) {
4865
4951
  setSelectedAmount(defaultAmount ?? null);
4866
4952
  setCustomAmount("");
@@ -4868,7 +4954,7 @@ function CreateCustomGameSheet({
4868
4954
  mutation.reset();
4869
4955
  }
4870
4956
  }, [visible]);
4871
- (0, import_react31.useEffect)(() => {
4957
+ (0, import_react32.useEffect)(() => {
4872
4958
  if (mutation.status === "success" && mutation.data) {
4873
4959
  onSuccess?.(mutation.data);
4874
4960
  const timer = setTimeout(() => {
@@ -4877,23 +4963,23 @@ function CreateCustomGameSheet({
4877
4963
  return () => clearTimeout(timer);
4878
4964
  }
4879
4965
  }, [mutation.status, mutation.data]);
4880
- (0, import_react31.useEffect)(() => {
4966
+ (0, import_react32.useEffect)(() => {
4881
4967
  if (mutation.status === "error" && mutation.error) {
4882
4968
  onError?.(mutation.error);
4883
4969
  }
4884
4970
  }, [mutation.status, mutation.error]);
4885
- const handlePresetSelect = (0, import_react31.useCallback)((amount) => {
4971
+ const handlePresetSelect = (0, import_react32.useCallback)((amount) => {
4886
4972
  setSelectedAmount(amount);
4887
4973
  setIsCustom(false);
4888
4974
  setCustomAmount("");
4889
4975
  onAmountChange?.(amount);
4890
4976
  }, [onAmountChange]);
4891
- const handleCustomSelect = (0, import_react31.useCallback)(() => {
4977
+ const handleCustomSelect = (0, import_react32.useCallback)(() => {
4892
4978
  setIsCustom(true);
4893
4979
  setSelectedAmount(null);
4894
4980
  onAmountChange?.(null);
4895
4981
  }, [onAmountChange]);
4896
- const handleCustomAmountChange = (0, import_react31.useCallback)((text) => {
4982
+ const handleCustomAmountChange = (0, import_react32.useCallback)((text) => {
4897
4983
  const cleaned = text.replace(/[^0-9.]/g, "").replace(/(\..*?)\..*/g, "$1");
4898
4984
  setCustomAmount(cleaned);
4899
4985
  const parsed = parseFloat(cleaned);
@@ -4908,7 +4994,7 @@ function CreateCustomGameSheet({
4908
4994
  const winnerTakes = pot * (1 - fee / 100);
4909
4995
  const isMutating = mutation.status !== "idle" && mutation.status !== "success" && mutation.status !== "error";
4910
4996
  const canCreate = finalAmount !== null && finalAmount > 0 && !isMutating && mutation.status !== "success";
4911
- const handleCreate = (0, import_react31.useCallback)(async () => {
4997
+ const handleCreate = (0, import_react32.useCallback)(async () => {
4912
4998
  if (!finalAmount || !wallet.publicKey) return;
4913
4999
  try {
4914
5000
  await mutation.execute({
@@ -5177,7 +5263,7 @@ var styles11 = import_react_native17.StyleSheet.create({
5177
5263
  });
5178
5264
 
5179
5265
  // src/ui/game/JoinGameSheet.tsx
5180
- var import_react32 = require("react");
5266
+ var import_react33 = require("react");
5181
5267
  var import_react_native18 = require("react-native");
5182
5268
  var import_jsx_runtime15 = require("react/jsx-runtime");
5183
5269
  var STATUS_LABELS3 = {
@@ -5203,22 +5289,22 @@ function JoinGameSheet({
5203
5289
  const { wallet } = useDubs();
5204
5290
  const mutation = useJoinGame();
5205
5291
  const isCustomGame = game.gameMode === CUSTOM_GAME_MODE;
5206
- const [selectedTeam, setSelectedTeam] = (0, import_react32.useState)(null);
5207
- const overlayOpacity = (0, import_react32.useRef)(new import_react_native18.Animated.Value(0)).current;
5208
- (0, import_react32.useEffect)(() => {
5292
+ const [selectedTeam, setSelectedTeam] = (0, import_react33.useState)(null);
5293
+ const overlayOpacity = (0, import_react33.useRef)(new import_react_native18.Animated.Value(0)).current;
5294
+ (0, import_react33.useEffect)(() => {
5209
5295
  import_react_native18.Animated.timing(overlayOpacity, {
5210
5296
  toValue: visible ? 1 : 0,
5211
5297
  duration: 250,
5212
5298
  useNativeDriver: true
5213
5299
  }).start();
5214
5300
  }, [visible, overlayOpacity]);
5215
- (0, import_react32.useEffect)(() => {
5301
+ (0, import_react33.useEffect)(() => {
5216
5302
  if (visible) {
5217
5303
  setSelectedTeam(isPoolModeEnabled ? "home" : isCustomGame ? "away" : null);
5218
5304
  mutation.reset();
5219
5305
  }
5220
5306
  }, [visible]);
5221
- (0, import_react32.useEffect)(() => {
5307
+ (0, import_react33.useEffect)(() => {
5222
5308
  if (mutation.status === "success" && mutation.data) {
5223
5309
  onSuccess?.(mutation.data);
5224
5310
  const timer = setTimeout(() => {
@@ -5227,7 +5313,7 @@ function JoinGameSheet({
5227
5313
  return () => clearTimeout(timer);
5228
5314
  }
5229
5315
  }, [mutation.status, mutation.data]);
5230
- (0, import_react32.useEffect)(() => {
5316
+ (0, import_react33.useEffect)(() => {
5231
5317
  if (mutation.status === "error" && mutation.error) {
5232
5318
  onError?.(mutation.error);
5233
5319
  }
@@ -5238,7 +5324,7 @@ function JoinGameSheet({
5238
5324
  const homePool = game.homePool || 0;
5239
5325
  const awayPool = game.awayPool || 0;
5240
5326
  const buyIn = game.buyIn;
5241
- const { homeOdds, awayOdds, homeBets, awayBets } = (0, import_react32.useMemo)(() => ({
5327
+ const { homeOdds, awayOdds, homeBets, awayBets } = (0, import_react33.useMemo)(() => ({
5242
5328
  homeOdds: homePool > 0 ? (totalPool / homePool).toFixed(2) : "\u2014",
5243
5329
  awayOdds: awayPool > 0 ? (totalPool / awayPool).toFixed(2) : "\u2014",
5244
5330
  homeBets: bettors.filter((b) => b.team === "home").length,
@@ -5250,14 +5336,14 @@ function JoinGameSheet({
5250
5336
  const homeName = shortName ? shortName(opponents[0]?.name) : opponents[0]?.name || "Home";
5251
5337
  const awayName = shortName ? shortName(opponents[1]?.name) : opponents[1]?.name || "Away";
5252
5338
  const selectedName = selectedTeam === "home" ? homeName : selectedTeam === "away" ? awayName : "\u2014";
5253
- const alreadyJoined = (0, import_react32.useMemo)(() => {
5339
+ const alreadyJoined = (0, import_react33.useMemo)(() => {
5254
5340
  if (!wallet.publicKey) return false;
5255
5341
  const addr = wallet.publicKey.toBase58();
5256
5342
  return bettors.some((b) => b.wallet === addr);
5257
5343
  }, [bettors, wallet.publicKey]);
5258
5344
  const isMutating = mutation.status !== "idle" && mutation.status !== "success" && mutation.status !== "error";
5259
5345
  const canJoin = selectedTeam !== null && !isMutating && mutation.status !== "success" && !alreadyJoined;
5260
- const handleJoin = (0, import_react32.useCallback)(async () => {
5346
+ const handleJoin = (0, import_react33.useCallback)(async () => {
5261
5347
  if (!selectedTeam || !wallet.publicKey) return;
5262
5348
  try {
5263
5349
  await mutation.execute({
@@ -5401,7 +5487,7 @@ function TeamButton({
5401
5487
  ImageComponent,
5402
5488
  t
5403
5489
  }) {
5404
- const [imgFailed, setImgFailed] = (0, import_react32.useState)(false);
5490
+ const [imgFailed, setImgFailed] = (0, import_react33.useState)(false);
5405
5491
  const Img = ImageComponent || require("react-native").Image;
5406
5492
  const showImage = imageUrl && !imgFailed;
5407
5493
  return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
@@ -5578,7 +5664,7 @@ var styles12 = import_react_native18.StyleSheet.create({
5578
5664
  });
5579
5665
 
5580
5666
  // src/ui/game/ClaimPrizeSheet.tsx
5581
- var import_react33 = require("react");
5667
+ var import_react34 = require("react");
5582
5668
  var import_react_native19 = require("react-native");
5583
5669
  var import_jsx_runtime16 = require("react/jsx-runtime");
5584
5670
  var STATUS_LABELS4 = {
@@ -5599,18 +5685,18 @@ function ClaimPrizeSheet({
5599
5685
  const t = useDubsTheme();
5600
5686
  const { wallet } = useDubs();
5601
5687
  const mutation = useClaim();
5602
- const overlayOpacity = (0, import_react33.useRef)(new import_react_native19.Animated.Value(0)).current;
5603
- const celebrationScale = (0, import_react33.useRef)(new import_react_native19.Animated.Value(0)).current;
5604
- const celebrationOpacity = (0, import_react33.useRef)(new import_react_native19.Animated.Value(0)).current;
5605
- const [showCelebration, setShowCelebration] = (0, import_react33.useState)(false);
5606
- (0, import_react33.useEffect)(() => {
5688
+ const overlayOpacity = (0, import_react34.useRef)(new import_react_native19.Animated.Value(0)).current;
5689
+ const celebrationScale = (0, import_react34.useRef)(new import_react_native19.Animated.Value(0)).current;
5690
+ const celebrationOpacity = (0, import_react34.useRef)(new import_react_native19.Animated.Value(0)).current;
5691
+ const [showCelebration, setShowCelebration] = (0, import_react34.useState)(false);
5692
+ (0, import_react34.useEffect)(() => {
5607
5693
  import_react_native19.Animated.timing(overlayOpacity, {
5608
5694
  toValue: visible ? 1 : 0,
5609
5695
  duration: 250,
5610
5696
  useNativeDriver: true
5611
5697
  }).start();
5612
5698
  }, [visible, overlayOpacity]);
5613
- (0, import_react33.useEffect)(() => {
5699
+ (0, import_react34.useEffect)(() => {
5614
5700
  if (visible) {
5615
5701
  mutation.reset();
5616
5702
  setShowCelebration(false);
@@ -5618,7 +5704,7 @@ function ClaimPrizeSheet({
5618
5704
  celebrationOpacity.setValue(0);
5619
5705
  }
5620
5706
  }, [visible]);
5621
- (0, import_react33.useEffect)(() => {
5707
+ (0, import_react34.useEffect)(() => {
5622
5708
  if (mutation.status === "success" && mutation.data) {
5623
5709
  setShowCelebration(true);
5624
5710
  import_react_native19.Animated.parallel([
@@ -5641,14 +5727,14 @@ function ClaimPrizeSheet({
5641
5727
  return () => clearTimeout(timer);
5642
5728
  }
5643
5729
  }, [mutation.status, mutation.data]);
5644
- (0, import_react33.useEffect)(() => {
5730
+ (0, import_react34.useEffect)(() => {
5645
5731
  if (mutation.status === "error" && mutation.error) {
5646
5732
  onError?.(mutation.error);
5647
5733
  }
5648
5734
  }, [mutation.status, mutation.error]);
5649
5735
  const isMutating = mutation.status !== "idle" && mutation.status !== "success" && mutation.status !== "error";
5650
5736
  const canClaim = !isMutating && mutation.status !== "success" && !!wallet.publicKey;
5651
- const handleClaim = (0, import_react33.useCallback)(async () => {
5737
+ const handleClaim = (0, import_react34.useCallback)(async () => {
5652
5738
  if (!wallet.publicKey) return;
5653
5739
  try {
5654
5740
  await mutation.execute({
@@ -5881,7 +5967,7 @@ var styles13 = import_react_native19.StyleSheet.create({
5881
5967
  });
5882
5968
 
5883
5969
  // src/ui/game/ClaimButton.tsx
5884
- var import_react34 = require("react");
5970
+ var import_react35 = require("react");
5885
5971
  var import_react_native20 = require("react-native");
5886
5972
  var import_jsx_runtime17 = require("react/jsx-runtime");
5887
5973
  function ClaimButton({ gameId, style, onSuccess, onError }) {
@@ -5889,9 +5975,9 @@ function ClaimButton({ gameId, style, onSuccess, onError }) {
5889
5975
  const { wallet } = useDubs();
5890
5976
  const game = useGame(gameId);
5891
5977
  const claimStatus = useHasClaimed(gameId);
5892
- const [sheetVisible, setSheetVisible] = (0, import_react34.useState)(false);
5978
+ const [sheetVisible, setSheetVisible] = (0, import_react35.useState)(false);
5893
5979
  const walletAddress = wallet.publicKey?.toBase58() ?? null;
5894
- const myBet = (0, import_react34.useMemo)(() => {
5980
+ const myBet = (0, import_react35.useMemo)(() => {
5895
5981
  if (!walletAddress || !game.data?.bettors) return null;
5896
5982
  return game.data.bettors.find((b) => b.wallet === walletAddress) ?? null;
5897
5983
  }, [walletAddress, game.data?.bettors]);
@@ -5900,7 +5986,7 @@ function ClaimButton({ gameId, style, onSuccess, onError }) {
5900
5986
  const isWinner = isResolved && myBet != null && myBet.team === game.data?.winnerSide;
5901
5987
  const isEligible = myBet != null && isResolved && (isWinner || isRefund);
5902
5988
  const prizeAmount = isRefund ? myBet?.amount ?? 0 : game.data?.totalPool ?? 0;
5903
- const handleSuccess = (0, import_react34.useCallback)(
5989
+ const handleSuccess = (0, import_react35.useCallback)(
5904
5990
  (result) => {
5905
5991
  claimStatus.refetch();
5906
5992
  onSuccess?.(result);
@@ -5987,7 +6073,7 @@ var styles14 = import_react_native20.StyleSheet.create({
5987
6073
  });
5988
6074
 
5989
6075
  // src/ui/game/EnterArcadePoolSheet.tsx
5990
- var import_react35 = require("react");
6076
+ var import_react36 = require("react");
5991
6077
  var import_react_native21 = require("react-native");
5992
6078
  var import_jsx_runtime18 = require("react/jsx-runtime");
5993
6079
  var STATUS_LABELS5 = {
@@ -6008,20 +6094,20 @@ function EnterArcadePoolSheet({
6008
6094
  const t = useDubsTheme();
6009
6095
  const { wallet } = useDubs();
6010
6096
  const mutation = useEnterArcadePool();
6011
- const overlayOpacity = (0, import_react35.useRef)(new import_react_native21.Animated.Value(0)).current;
6012
- (0, import_react35.useEffect)(() => {
6097
+ const overlayOpacity = (0, import_react36.useRef)(new import_react_native21.Animated.Value(0)).current;
6098
+ (0, import_react36.useEffect)(() => {
6013
6099
  import_react_native21.Animated.timing(overlayOpacity, {
6014
6100
  toValue: visible ? 1 : 0,
6015
6101
  duration: 250,
6016
6102
  useNativeDriver: true
6017
6103
  }).start();
6018
6104
  }, [visible, overlayOpacity]);
6019
- (0, import_react35.useEffect)(() => {
6105
+ (0, import_react36.useEffect)(() => {
6020
6106
  if (visible) {
6021
6107
  mutation.reset();
6022
6108
  }
6023
6109
  }, [visible]);
6024
- (0, import_react35.useEffect)(() => {
6110
+ (0, import_react36.useEffect)(() => {
6025
6111
  if (mutation.status === "success" && mutation.data) {
6026
6112
  onSuccess?.(mutation.data);
6027
6113
  const timer = setTimeout(() => {
@@ -6030,7 +6116,7 @@ function EnterArcadePoolSheet({
6030
6116
  return () => clearTimeout(timer);
6031
6117
  }
6032
6118
  }, [mutation.status, mutation.data]);
6033
- (0, import_react35.useEffect)(() => {
6119
+ (0, import_react36.useEffect)(() => {
6034
6120
  if (mutation.status === "error" && mutation.error) {
6035
6121
  onError?.(mutation.error);
6036
6122
  }
@@ -6041,7 +6127,7 @@ function EnterArcadePoolSheet({
6041
6127
  const potSol = (pool.buy_in_lamports * Number(totalPlayers) / 1e9).toFixed(4);
6042
6128
  const isMutating = mutation.status !== "idle" && mutation.status !== "success" && mutation.status !== "error";
6043
6129
  const canJoin = !isMutating && mutation.status !== "success";
6044
- const handleJoin = (0, import_react35.useCallback)(async () => {
6130
+ const handleJoin = (0, import_react36.useCallback)(async () => {
6045
6131
  if (!wallet.publicKey) return;
6046
6132
  try {
6047
6133
  await mutation.execute(pool.id);
@@ -6192,7 +6278,7 @@ var styles15 = import_react_native21.StyleSheet.create({
6192
6278
  });
6193
6279
 
6194
6280
  // src/ui/game/ArcadeLeaderboardSheet.tsx
6195
- var import_react36 = require("react");
6281
+ var import_react37 = require("react");
6196
6282
  var import_react_native22 = require("react-native");
6197
6283
  var import_jsx_runtime19 = require("react/jsx-runtime");
6198
6284
  function RankLabel({ index }) {
@@ -6209,15 +6295,15 @@ function ArcadeLeaderboardSheet({
6209
6295
  }) {
6210
6296
  const t = useDubsTheme();
6211
6297
  const { pool, leaderboard, stats, loading, refetch } = useArcadePool(poolId);
6212
- const overlayOpacity = (0, import_react36.useRef)(new import_react_native22.Animated.Value(0)).current;
6213
- (0, import_react36.useEffect)(() => {
6298
+ const overlayOpacity = (0, import_react37.useRef)(new import_react_native22.Animated.Value(0)).current;
6299
+ (0, import_react37.useEffect)(() => {
6214
6300
  import_react_native22.Animated.timing(overlayOpacity, {
6215
6301
  toValue: visible ? 1 : 0,
6216
6302
  duration: 250,
6217
6303
  useNativeDriver: true
6218
6304
  }).start();
6219
6305
  }, [visible, overlayOpacity]);
6220
- (0, import_react36.useEffect)(() => {
6306
+ (0, import_react37.useEffect)(() => {
6221
6307
  if (visible) refetch();
6222
6308
  }, [visible]);
6223
6309
  const renderItem = ({ item, index }) => {
@@ -6398,6 +6484,7 @@ var styles16 = import_react_native22.StyleSheet.create({
6398
6484
  parseSolanaError,
6399
6485
  signAndSendBase64Transaction,
6400
6486
  useAppConfig,
6487
+ useArcadeBridge,
6401
6488
  useArcadeCountdown,
6402
6489
  useArcadeGame,
6403
6490
  useArcadePool,