@dubsdotapp/expo 0.1.1 → 0.1.3

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
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
+ AuthGate: () => AuthGate,
33
34
  ConnectWalletScreen: () => ConnectWalletScreen,
34
35
  DEFAULT_BASE_URL: () => DEFAULT_BASE_URL,
35
36
  DEFAULT_RPC_URL: () => DEFAULT_RPC_URL,
@@ -908,7 +909,7 @@ function useAuth() {
908
909
  setStatus("error");
909
910
  }
910
911
  }, [client, wallet]);
911
- const register = (0, import_react9.useCallback)(async (username, referralCode) => {
912
+ const register = (0, import_react9.useCallback)(async (username, referralCode, avatarUrl) => {
912
913
  try {
913
914
  const pending = pendingAuth.current;
914
915
  if (!pending) {
@@ -921,7 +922,8 @@ function useAuth() {
921
922
  signature: pending.signature,
922
923
  nonce: pending.nonce,
923
924
  username,
924
- referralCode
925
+ referralCode,
926
+ avatarUrl
925
927
  });
926
928
  pendingAuth.current = null;
927
929
  setUser(result.user);
@@ -973,7 +975,8 @@ function useAuth() {
973
975
  };
974
976
  }
975
977
 
976
- // src/ui/ConnectWalletScreen.tsx
978
+ // src/ui/AuthGate.tsx
979
+ var import_react10 = __toESM(require("react"));
977
980
  var import_react_native2 = require("react-native");
978
981
 
979
982
  // src/ui/theme.ts
@@ -1015,8 +1018,503 @@ function useDubsTheme() {
1015
1018
  return scheme === "light" ? light : dark;
1016
1019
  }
1017
1020
 
1018
- // src/ui/ConnectWalletScreen.tsx
1021
+ // src/ui/AuthGate.tsx
1019
1022
  var import_jsx_runtime2 = require("react/jsx-runtime");
1023
+ var DICEBEAR_STYLES = [
1024
+ "adventurer",
1025
+ "avataaars",
1026
+ "fun-emoji",
1027
+ "bottts",
1028
+ "big-smile",
1029
+ "thumbs"
1030
+ ];
1031
+ function generateSeed() {
1032
+ return Math.random().toString(36).slice(2, 10);
1033
+ }
1034
+ function getAvatarUrl(style, seed, size = 256) {
1035
+ return `https://api.dicebear.com/9.x/${style}/png?seed=${seed}&size=${size}`;
1036
+ }
1037
+ function AuthGate({
1038
+ children,
1039
+ onSaveToken,
1040
+ onLoadToken,
1041
+ renderLoading,
1042
+ renderError,
1043
+ renderRegistration,
1044
+ appName = "Dubs"
1045
+ }) {
1046
+ const { client } = useDubs();
1047
+ const auth = useAuth();
1048
+ const [phase, setPhase] = (0, import_react10.useState)("init");
1049
+ const [registrationPhase, setRegistrationPhase] = (0, import_react10.useState)(false);
1050
+ (0, import_react10.useEffect)(() => {
1051
+ let cancelled = false;
1052
+ (async () => {
1053
+ try {
1054
+ const savedToken = await onLoadToken();
1055
+ if (cancelled) return;
1056
+ if (savedToken) {
1057
+ const restored = await auth.restoreSession(savedToken);
1058
+ if (cancelled) return;
1059
+ if (restored) {
1060
+ setPhase("active");
1061
+ return;
1062
+ }
1063
+ await onSaveToken(null);
1064
+ }
1065
+ if (cancelled) return;
1066
+ setPhase("active");
1067
+ await auth.authenticate();
1068
+ } catch {
1069
+ if (!cancelled) setPhase("active");
1070
+ }
1071
+ })();
1072
+ return () => {
1073
+ cancelled = true;
1074
+ };
1075
+ }, []);
1076
+ (0, import_react10.useEffect)(() => {
1077
+ if (auth.status === "needsRegistration") setRegistrationPhase(true);
1078
+ }, [auth.status]);
1079
+ (0, import_react10.useEffect)(() => {
1080
+ if (auth.token) onSaveToken(auth.token);
1081
+ }, [auth.token]);
1082
+ const retry = (0, import_react10.useCallback)(() => {
1083
+ setRegistrationPhase(false);
1084
+ auth.reset();
1085
+ auth.authenticate();
1086
+ }, [auth]);
1087
+ const handleRegister = (0, import_react10.useCallback)(
1088
+ (username, referralCode, avatarUrl) => {
1089
+ auth.register(username, referralCode, avatarUrl);
1090
+ },
1091
+ [auth]
1092
+ );
1093
+ if (phase === "init") {
1094
+ if (renderLoading) return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children: renderLoading("authenticating") });
1095
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DefaultLoadingScreen, { status: "authenticating", appName });
1096
+ }
1097
+ if (auth.status === "authenticated") return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children });
1098
+ if (registrationPhase) {
1099
+ const isRegistering = auth.status === "registering";
1100
+ const regError = auth.status === "error" ? auth.error : null;
1101
+ if (renderRegistration) {
1102
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children: renderRegistration({ onRegister: handleRegister, registering: isRegistering, error: regError, client }) });
1103
+ }
1104
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1105
+ DefaultRegistrationScreen,
1106
+ {
1107
+ onRegister: handleRegister,
1108
+ registering: isRegistering,
1109
+ error: regError,
1110
+ client,
1111
+ appName
1112
+ }
1113
+ );
1114
+ }
1115
+ if (auth.status === "error" && auth.error) {
1116
+ if (renderError) return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children: renderError(auth.error, retry) });
1117
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DefaultErrorScreen, { error: auth.error, onRetry: retry, appName });
1118
+ }
1119
+ if (renderLoading) return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children: renderLoading(auth.status) });
1120
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DefaultLoadingScreen, { status: auth.status, appName });
1121
+ }
1122
+ function DefaultLoadingScreen({ status, appName }) {
1123
+ const t = useDubsTheme();
1124
+ const statusText = {
1125
+ idle: "Initializing...",
1126
+ authenticating: "Connecting...",
1127
+ signing: "Approve in your wallet...",
1128
+ verifying: "Verifying...",
1129
+ registering: "Creating account...",
1130
+ needsRegistration: "Almost there...",
1131
+ authenticated: "Ready!",
1132
+ error: "Something went wrong"
1133
+ };
1134
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.View, { style: [s.container, { backgroundColor: t.background }], children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: s.centerContent, children: [
1135
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: s.brandingSection, children: [
1136
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.View, { style: [s.logoCircle, { backgroundColor: t.accent }], children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: s.logoText, children: "D" }) }),
1137
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: [s.appNameText, { color: t.text }], children: appName })
1138
+ ] }),
1139
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: s.loadingSection, children: [
1140
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.ActivityIndicator, { size: "large", color: t.accent }),
1141
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: [s.statusText, { color: t.textMuted }], children: statusText[status] || "Loading..." })
1142
+ ] })
1143
+ ] }) });
1144
+ }
1145
+ function DefaultErrorScreen({ error, onRetry, appName }) {
1146
+ const t = useDubsTheme();
1147
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.View, { style: [s.container, { backgroundColor: t.background }], children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: s.spreadContent, children: [
1148
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: s.brandingSection, children: [
1149
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.View, { style: [s.logoCircle, { backgroundColor: t.accent }], children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: s.logoText, children: "D" }) }),
1150
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: [s.appNameText, { color: t.text }], children: appName })
1151
+ ] }),
1152
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: { gap: 16 }, children: [
1153
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.View, { style: [s.errorBox, { backgroundColor: t.errorBg, borderColor: t.errorBorder }], children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: [s.errorText, { color: t.errorText }], children: error.message }) }),
1154
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.TouchableOpacity, { style: [s.primaryBtn, { backgroundColor: t.accent }], onPress: onRetry, activeOpacity: 0.8, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: s.primaryBtnText, children: "Try Again" }) })
1155
+ ] })
1156
+ ] }) });
1157
+ }
1158
+ function StepIndicator({ currentStep }) {
1159
+ const t = useDubsTheme();
1160
+ const steps = [0, 1, 2, 3];
1161
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.View, { style: s.stepRow, children: steps.map((i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react10.default.Fragment, { children: [
1162
+ i > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.View, { style: [s.stepLine, { backgroundColor: i <= currentStep ? t.success : t.border }] }),
1163
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1164
+ import_react_native2.View,
1165
+ {
1166
+ style: [
1167
+ s.stepCircle,
1168
+ i < currentStep ? { backgroundColor: t.success } : i === currentStep ? { backgroundColor: t.accent } : { backgroundColor: "transparent", borderWidth: 2, borderColor: t.border }
1169
+ ],
1170
+ children: i < currentStep ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: s.stepCheck, children: "\u2713" }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: [s.stepNum, { color: i === currentStep ? "#FFF" : t.textMuted }], children: i + 1 })
1171
+ }
1172
+ )
1173
+ ] }, i)) });
1174
+ }
1175
+ function DefaultRegistrationScreen({
1176
+ onRegister,
1177
+ registering,
1178
+ error,
1179
+ client,
1180
+ appName
1181
+ }) {
1182
+ const t = useDubsTheme();
1183
+ const [step, setStep] = (0, import_react10.useState)(0);
1184
+ const [avatarSeed, setAvatarSeed] = (0, import_react10.useState)(generateSeed);
1185
+ const [avatarStyle, setAvatarStyle] = (0, import_react10.useState)("adventurer");
1186
+ const [showStyles, setShowStyles] = (0, import_react10.useState)(false);
1187
+ const [username, setUsername] = (0, import_react10.useState)("");
1188
+ const [referralCode, setReferralCode] = (0, import_react10.useState)("");
1189
+ const [checking, setChecking] = (0, import_react10.useState)(false);
1190
+ const [availability, setAvailability] = (0, import_react10.useState)(null);
1191
+ const debounceRef = (0, import_react10.useRef)(null);
1192
+ const fadeAnim = (0, import_react10.useRef)(new import_react_native2.Animated.Value(1)).current;
1193
+ const slideAnim = (0, import_react10.useRef)(new import_react_native2.Animated.Value(0)).current;
1194
+ const avatarUrl = getAvatarUrl(avatarStyle, avatarSeed);
1195
+ (0, import_react10.useEffect)(() => {
1196
+ if (debounceRef.current) clearTimeout(debounceRef.current);
1197
+ const trimmed = username.trim();
1198
+ if (trimmed.length < 3) {
1199
+ setAvailability(null);
1200
+ setChecking(false);
1201
+ return;
1202
+ }
1203
+ setChecking(true);
1204
+ debounceRef.current = setTimeout(async () => {
1205
+ try {
1206
+ const result = await client.checkUsername(trimmed);
1207
+ setAvailability(result);
1208
+ } catch {
1209
+ setAvailability(null);
1210
+ } finally {
1211
+ setChecking(false);
1212
+ }
1213
+ }, 500);
1214
+ return () => {
1215
+ if (debounceRef.current) clearTimeout(debounceRef.current);
1216
+ };
1217
+ }, [username, client]);
1218
+ const animateToStep = (0, import_react10.useCallback)((newStep) => {
1219
+ const dir = newStep > step ? 1 : -1;
1220
+ import_react_native2.Keyboard.dismiss();
1221
+ import_react_native2.Animated.parallel([
1222
+ import_react_native2.Animated.timing(fadeAnim, { toValue: 0, duration: 120, useNativeDriver: true }),
1223
+ import_react_native2.Animated.timing(slideAnim, { toValue: -dir * 40, duration: 120, useNativeDriver: true })
1224
+ ]).start(() => {
1225
+ setStep(newStep);
1226
+ slideAnim.setValue(dir * 40);
1227
+ import_react_native2.Animated.parallel([
1228
+ import_react_native2.Animated.timing(fadeAnim, { toValue: 1, duration: 200, useNativeDriver: true }),
1229
+ import_react_native2.Animated.timing(slideAnim, { toValue: 0, duration: 200, useNativeDriver: true })
1230
+ ]).start();
1231
+ });
1232
+ }, [step, fadeAnim, slideAnim]);
1233
+ const canContinueUsername = username.trim().length >= 3 && availability?.available === true && !checking;
1234
+ const handleSubmit = () => {
1235
+ import_react_native2.Keyboard.dismiss();
1236
+ onRegister(username.trim(), referralCode.trim() || void 0, avatarUrl);
1237
+ };
1238
+ const renderAvatarStep = () => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: s.stepContainer, children: [
1239
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: s.stepTop, children: [
1240
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: [s.title, { color: t.text }], children: "Choose Your Avatar" }),
1241
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: [s.subtitle, { color: t.textMuted }], children: "Pick a look that represents you" }),
1242
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(StepIndicator, { currentStep: 0 }),
1243
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.View, { style: s.avatarCenter, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: [s.avatarFrame, { borderColor: t.accent }], children: [
1244
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Image, { source: { uri: avatarUrl }, style: s.avatarLarge }),
1245
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.View, { style: [s.checkBadge, { backgroundColor: t.success }], children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: s.checkBadgeText, children: "\u2713" }) })
1246
+ ] }) }),
1247
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: s.avatarActions, children: [
1248
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1249
+ import_react_native2.TouchableOpacity,
1250
+ {
1251
+ style: [s.outlineBtn, { borderColor: t.border }],
1252
+ onPress: () => setAvatarSeed(generateSeed()),
1253
+ activeOpacity: 0.7,
1254
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: [s.outlineBtnText, { color: t.text }], children: "\u21BB Shuffle" })
1255
+ }
1256
+ ),
1257
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1258
+ import_react_native2.TouchableOpacity,
1259
+ {
1260
+ style: [s.outlineBtn, { borderColor: t.accent, backgroundColor: t.accent + "15" }],
1261
+ onPress: () => setShowStyles(!showStyles),
1262
+ activeOpacity: 0.7,
1263
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: [s.outlineBtnText, { color: t.accent }], children: "\u263A Customize" })
1264
+ }
1265
+ )
1266
+ ] }),
1267
+ showStyles && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.ScrollView, { horizontal: true, showsHorizontalScrollIndicator: false, style: s.styleScroll, children: DICEBEAR_STYLES.map((st) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1268
+ import_react_native2.TouchableOpacity,
1269
+ {
1270
+ onPress: () => setAvatarStyle(st),
1271
+ style: [s.styleThumbWrap, { borderColor: st === avatarStyle ? t.accent : t.border }],
1272
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Image, { source: { uri: getAvatarUrl(st, avatarSeed, 80) }, style: s.styleThumb })
1273
+ },
1274
+ st
1275
+ )) })
1276
+ ] }),
1277
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.View, { style: s.bottomRow, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1278
+ import_react_native2.TouchableOpacity,
1279
+ {
1280
+ style: [s.primaryBtn, { backgroundColor: t.accent, flex: 1 }],
1281
+ onPress: () => animateToStep(1),
1282
+ activeOpacity: 0.8,
1283
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: s.primaryBtnText, children: "Continue \u203A" })
1284
+ }
1285
+ ) })
1286
+ ] });
1287
+ const renderUsernameStep = () => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: s.stepContainer, children: [
1288
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: s.stepTop, children: [
1289
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: s.headerRow, children: [
1290
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.TouchableOpacity, { onPress: () => animateToStep(0), hitSlop: { top: 12, bottom: 12, left: 12, right: 12 }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: [s.backChevron, { color: t.text }], children: "\u2039" }) }),
1291
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: [s.titleInline, { color: t.text }], children: "Pick a Username" })
1292
+ ] }),
1293
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: [s.subtitle, { color: t.textMuted }], children: "This is how others will see you" }),
1294
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(StepIndicator, { currentStep: 1 }),
1295
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.View, { style: s.avatarCenter, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: [s.avatarFrameSmall, { borderColor: t.accent }], children: [
1296
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Image, { source: { uri: avatarUrl }, style: s.avatarSmall }),
1297
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.View, { style: [s.checkBadgeSm, { backgroundColor: t.success }], children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: s.checkBadgeTextSm, children: "\u2713" }) })
1298
+ ] }) }),
1299
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: s.inputGroup, children: [
1300
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.Text, { style: [s.inputLabel, { color: t.text }], children: [
1301
+ "Username ",
1302
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: { color: t.errorText }, children: "*" })
1303
+ ] }),
1304
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1305
+ import_react_native2.TextInput,
1306
+ {
1307
+ style: [s.input, { backgroundColor: t.surface, color: t.text, borderColor: t.accent }],
1308
+ placeholder: "Enter username",
1309
+ placeholderTextColor: t.textDim,
1310
+ value: username,
1311
+ onChangeText: setUsername,
1312
+ autoCapitalize: "none",
1313
+ autoCorrect: false,
1314
+ autoFocus: true
1315
+ }
1316
+ ),
1317
+ checking ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: [s.hint, { color: t.textDim }], children: "Checking..." }) : availability ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: [s.hint, { color: availability.available ? t.success : t.errorText }], children: availability.available ? "\u2713 Available!" : availability.reason || "Username taken" }) : username.trim().length > 0 && username.trim().length < 3 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: [s.hint, { color: t.textDim }], children: "At least 3 characters" }) : null
1318
+ ] })
1319
+ ] }),
1320
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: s.bottomRow, children: [
1321
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1322
+ import_react_native2.TouchableOpacity,
1323
+ {
1324
+ style: [s.secondaryBtn, { borderColor: t.border }],
1325
+ onPress: () => animateToStep(0),
1326
+ activeOpacity: 0.7,
1327
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: [s.secondaryBtnText, { color: t.text }], children: "\u2039 Back" })
1328
+ }
1329
+ ),
1330
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1331
+ import_react_native2.TouchableOpacity,
1332
+ {
1333
+ style: [s.primaryBtn, { backgroundColor: t.accent, flex: 1, opacity: canContinueUsername ? 1 : 0.4 }],
1334
+ onPress: () => animateToStep(2),
1335
+ disabled: !canContinueUsername,
1336
+ activeOpacity: 0.8,
1337
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: s.primaryBtnText, children: "Continue \u203A" })
1338
+ }
1339
+ )
1340
+ ] })
1341
+ ] });
1342
+ const renderReferralStep = () => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: s.stepContainer, children: [
1343
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: s.stepTop, children: [
1344
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: s.headerRow, children: [
1345
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.TouchableOpacity, { onPress: () => animateToStep(1), hitSlop: { top: 12, bottom: 12, left: 12, right: 12 }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: [s.backChevron, { color: t.text }], children: "\u2039" }) }),
1346
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: [s.titleInline, { color: t.text }], children: "Almost There!" })
1347
+ ] }),
1348
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: [s.subtitle, { color: t.textMuted }], children: "Got a referral code? (optional)" }),
1349
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(StepIndicator, { currentStep: 2 }),
1350
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: [s.profileCard, { borderColor: t.border }], children: [
1351
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: [s.profileLabel, { color: t.textMuted }], children: "Your Profile" }),
1352
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: s.profileRow, children: [
1353
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Image, { source: { uri: avatarUrl }, style: s.profileAvatar }),
1354
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: { gap: 4 }, children: [
1355
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.Text, { style: [s.profileUsername, { color: t.text }], children: [
1356
+ "@",
1357
+ username
1358
+ ] }),
1359
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.Text, { style: [s.profileReady, { color: t.success }], children: [
1360
+ "\u2713",
1361
+ " Ready to go!"
1362
+ ] })
1363
+ ] })
1364
+ ] })
1365
+ ] }),
1366
+ error ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.View, { style: [s.errorBox, { backgroundColor: t.errorBg, borderColor: t.errorBorder }], children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: [s.errorText, { color: t.errorText }], children: error.message }) }) : null,
1367
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: s.inputGroup, children: [
1368
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.Text, { style: [s.inputLabel, { color: t.text }], children: [
1369
+ "Referral Code ",
1370
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: { color: t.textMuted }, children: "(optional)" })
1371
+ ] }),
1372
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1373
+ import_react_native2.TextInput,
1374
+ {
1375
+ style: [s.input, { backgroundColor: t.surface, color: t.text, borderColor: t.border }],
1376
+ placeholder: "Enter referral code",
1377
+ placeholderTextColor: t.textDim,
1378
+ value: referralCode,
1379
+ onChangeText: setReferralCode,
1380
+ autoCapitalize: "none",
1381
+ autoCorrect: false,
1382
+ editable: !registering
1383
+ }
1384
+ ),
1385
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.Text, { style: [s.hint, { color: t.textMuted }], children: [
1386
+ "\u{1F381}",
1387
+ " If a friend invited you, enter their code to give them credit!"
1388
+ ] })
1389
+ ] })
1390
+ ] }),
1391
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: s.bottomRow, children: [
1392
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1393
+ import_react_native2.TouchableOpacity,
1394
+ {
1395
+ style: [s.secondaryBtn, { borderColor: t.border }],
1396
+ onPress: () => animateToStep(1),
1397
+ disabled: registering,
1398
+ activeOpacity: 0.7,
1399
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: [s.secondaryBtnText, { color: t.text }], children: "\u2039 Back" })
1400
+ }
1401
+ ),
1402
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1403
+ import_react_native2.TouchableOpacity,
1404
+ {
1405
+ style: [s.primaryBtn, { backgroundColor: t.accent, flex: 1, opacity: registering ? 0.7 : 1 }],
1406
+ onPress: handleSubmit,
1407
+ disabled: registering,
1408
+ activeOpacity: 0.8,
1409
+ children: registering ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.ActivityIndicator, { color: "#FFFFFF", size: "small" }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: s.primaryBtnText, children: "Create Account" })
1410
+ }
1411
+ )
1412
+ ] })
1413
+ ] });
1414
+ const renderStep = () => {
1415
+ switch (step) {
1416
+ case 0:
1417
+ return renderAvatarStep();
1418
+ case 1:
1419
+ return renderUsernameStep();
1420
+ case 2:
1421
+ return renderReferralStep();
1422
+ default:
1423
+ return null;
1424
+ }
1425
+ };
1426
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1427
+ import_react_native2.KeyboardAvoidingView,
1428
+ {
1429
+ style: [s.container, { backgroundColor: t.background }],
1430
+ behavior: import_react_native2.Platform.OS === "ios" ? "padding" : void 0,
1431
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1432
+ import_react_native2.ScrollView,
1433
+ {
1434
+ contentContainerStyle: { flexGrow: 1 },
1435
+ keyboardShouldPersistTaps: "handled",
1436
+ bounces: false,
1437
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1438
+ import_react_native2.Animated.View,
1439
+ {
1440
+ style: [
1441
+ { flex: 1 },
1442
+ { opacity: fadeAnim, transform: [{ translateX: slideAnim }] }
1443
+ ],
1444
+ children: renderStep()
1445
+ }
1446
+ )
1447
+ }
1448
+ )
1449
+ }
1450
+ );
1451
+ }
1452
+ var s = import_react_native2.StyleSheet.create({
1453
+ container: { flex: 1 },
1454
+ // Loading / Error
1455
+ centerContent: { flex: 1, justifyContent: "center", alignItems: "center", paddingHorizontal: 32, gap: 48 },
1456
+ spreadContent: { flex: 1, justifyContent: "space-between", paddingHorizontal: 32, paddingTop: 120, paddingBottom: 80 },
1457
+ brandingSection: { alignItems: "center", gap: 12 },
1458
+ logoCircle: { width: 80, height: 80, borderRadius: 40, justifyContent: "center", alignItems: "center", marginBottom: 8 },
1459
+ logoText: { fontSize: 36, fontWeight: "800", color: "#FFFFFF" },
1460
+ appNameText: { fontSize: 32, fontWeight: "800" },
1461
+ loadingSection: { alignItems: "center", gap: 16 },
1462
+ statusText: { fontSize: 16, textAlign: "center" },
1463
+ errorBox: { borderWidth: 1, borderRadius: 12, paddingHorizontal: 16, paddingVertical: 12 },
1464
+ errorText: { fontSize: 14, textAlign: "center" },
1465
+ // Step indicator
1466
+ stepRow: { flexDirection: "row", alignItems: "center", paddingHorizontal: 24, marginVertical: 16 },
1467
+ stepLine: { flex: 1, height: 2 },
1468
+ stepCircle: { width: 36, height: 36, borderRadius: 18, justifyContent: "center", alignItems: "center" },
1469
+ stepCheck: { color: "#FFF", fontSize: 16, fontWeight: "700" },
1470
+ stepNum: { fontSize: 14, fontWeight: "700" },
1471
+ // Onboarding layout
1472
+ stepContainer: { flex: 1, justifyContent: "space-between", paddingBottom: 40 },
1473
+ stepTop: { gap: 8, paddingTop: 64 },
1474
+ headerRow: { flexDirection: "row", alignItems: "center", gap: 8, paddingHorizontal: 24 },
1475
+ backChevron: { fontSize: 32, fontWeight: "300", lineHeight: 36, marginTop: -2 },
1476
+ title: { fontSize: 28, fontWeight: "800", paddingHorizontal: 24 },
1477
+ titleInline: { fontSize: 28, fontWeight: "800" },
1478
+ subtitle: { fontSize: 15, paddingHorizontal: 24, lineHeight: 20 },
1479
+ // Avatar
1480
+ avatarCenter: { alignItems: "center", marginVertical: 12 },
1481
+ avatarFrame: { borderWidth: 3, borderRadius: 20, padding: 4 },
1482
+ avatarLarge: { width: 160, height: 160, borderRadius: 16, backgroundColor: "#E5E5EA" },
1483
+ checkBadge: { position: "absolute", bottom: -6, right: -6, width: 28, height: 28, borderRadius: 14, justifyContent: "center", alignItems: "center" },
1484
+ checkBadgeText: { color: "#FFF", fontSize: 15, fontWeight: "700" },
1485
+ avatarFrameSmall: { borderWidth: 3, borderRadius: 14, padding: 3 },
1486
+ avatarSmall: { width: 100, height: 100, borderRadius: 12, backgroundColor: "#E5E5EA" },
1487
+ checkBadgeSm: { position: "absolute", bottom: -4, right: -4, width: 22, height: 22, borderRadius: 11, justifyContent: "center", alignItems: "center" },
1488
+ checkBadgeTextSm: { color: "#FFF", fontSize: 12, fontWeight: "700" },
1489
+ avatarActions: { flexDirection: "row", justifyContent: "center", gap: 12, paddingHorizontal: 24 },
1490
+ outlineBtn: { borderWidth: 1.5, borderRadius: 12, paddingHorizontal: 20, paddingVertical: 12 },
1491
+ outlineBtnText: { fontSize: 15, fontWeight: "600" },
1492
+ styleScroll: { paddingHorizontal: 24, marginTop: 4 },
1493
+ styleThumbWrap: { borderWidth: 2, borderRadius: 12, padding: 3, marginRight: 10 },
1494
+ styleThumb: { width: 52, height: 52, borderRadius: 10, backgroundColor: "#E5E5EA" },
1495
+ // Input
1496
+ inputGroup: { paddingHorizontal: 24, gap: 6 },
1497
+ inputLabel: { fontSize: 15, fontWeight: "600" },
1498
+ input: { height: 56, borderRadius: 16, borderWidth: 1.5, paddingHorizontal: 16, fontSize: 16 },
1499
+ hint: { fontSize: 13, paddingLeft: 4 },
1500
+ // Profile card
1501
+ profileCard: { marginHorizontal: 24, borderWidth: 1, borderRadius: 16, padding: 16, gap: 12 },
1502
+ profileLabel: { fontSize: 13 },
1503
+ profileRow: { flexDirection: "row", alignItems: "center", gap: 14 },
1504
+ profileAvatar: { width: 56, height: 56, borderRadius: 12, backgroundColor: "#E5E5EA" },
1505
+ profileUsername: { fontSize: 20, fontWeight: "800" },
1506
+ profileReady: { fontSize: 14, fontWeight: "600" },
1507
+ // Buttons
1508
+ bottomRow: { flexDirection: "row", gap: 12, paddingHorizontal: 24 },
1509
+ primaryBtn: { height: 56, borderRadius: 16, justifyContent: "center", alignItems: "center" },
1510
+ primaryBtnText: { color: "#FFFFFF", fontSize: 18, fontWeight: "700" },
1511
+ secondaryBtn: { height: 56, borderRadius: 16, borderWidth: 1.5, justifyContent: "center", alignItems: "center", paddingHorizontal: 24 },
1512
+ secondaryBtnText: { fontSize: 16, fontWeight: "600" }
1513
+ });
1514
+
1515
+ // src/ui/ConnectWalletScreen.tsx
1516
+ var import_react_native3 = require("react-native");
1517
+ var import_jsx_runtime3 = require("react/jsx-runtime");
1020
1518
  function ConnectWalletScreen({
1021
1519
  onConnect,
1022
1520
  connecting = false,
@@ -1024,38 +1522,38 @@ function ConnectWalletScreen({
1024
1522
  appName = "Dubs"
1025
1523
  }) {
1026
1524
  const t = useDubsTheme();
1027
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.View, { style: [styles.container, { backgroundColor: t.background }], children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: styles.content, children: [
1028
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: styles.brandingSection, children: [
1029
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.View, { style: [styles.logoCircle, { backgroundColor: t.accent }], children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: styles.logoText, children: "D" }) }),
1030
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: [styles.appName, { color: t.text }], children: appName }),
1031
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: [styles.subtitle, { color: t.textMuted }], children: "Connect your Solana wallet to get started" })
1525
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native3.View, { style: [styles.container, { backgroundColor: t.background }], children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native3.View, { style: styles.content, children: [
1526
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native3.View, { style: styles.brandingSection, children: [
1527
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native3.View, { style: [styles.logoCircle, { backgroundColor: t.accent }], children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native3.Text, { style: styles.logoText, children: "D" }) }),
1528
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native3.Text, { style: [styles.appName, { color: t.text }], children: appName }),
1529
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native3.Text, { style: [styles.subtitle, { color: t.textMuted }], children: "Connect your Solana wallet to get started" })
1032
1530
  ] }),
1033
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: styles.actionSection, children: [
1034
- error ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1035
- import_react_native2.View,
1531
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native3.View, { style: styles.actionSection, children: [
1532
+ error ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1533
+ import_react_native3.View,
1036
1534
  {
1037
1535
  style: [
1038
1536
  styles.errorBox,
1039
1537
  { backgroundColor: t.errorBg, borderColor: t.errorBorder }
1040
1538
  ],
1041
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: [styles.errorText, { color: t.errorText }], children: error })
1539
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native3.Text, { style: [styles.errorText, { color: t.errorText }], children: error })
1042
1540
  }
1043
1541
  ) : null,
1044
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1045
- import_react_native2.TouchableOpacity,
1542
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1543
+ import_react_native3.TouchableOpacity,
1046
1544
  {
1047
1545
  style: [styles.connectButton, { backgroundColor: t.accent }],
1048
1546
  onPress: onConnect,
1049
1547
  disabled: connecting,
1050
1548
  activeOpacity: 0.8,
1051
- children: connecting ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.ActivityIndicator, { color: "#FFFFFF", size: "small" }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: styles.connectButtonText, children: "Connect Wallet" })
1549
+ children: connecting ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native3.ActivityIndicator, { color: "#FFFFFF", size: "small" }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native3.Text, { style: styles.connectButtonText, children: "Connect Wallet" })
1052
1550
  }
1053
1551
  ),
1054
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: [styles.hint, { color: t.textDim }], children: "Phantom, Solflare, or any Solana wallet" })
1552
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native3.Text, { style: [styles.hint, { color: t.textDim }], children: "Phantom, Solflare, or any Solana wallet" })
1055
1553
  ] })
1056
1554
  ] }) });
1057
1555
  }
1058
- var styles = import_react_native2.StyleSheet.create({
1556
+ var styles = import_react_native3.StyleSheet.create({
1059
1557
  container: {
1060
1558
  flex: 1,
1061
1559
  justifyContent: "center"
@@ -1124,9 +1622,9 @@ var styles = import_react_native2.StyleSheet.create({
1124
1622
  });
1125
1623
 
1126
1624
  // src/ui/UserProfileCard.tsx
1127
- var import_react10 = require("react");
1128
- var import_react_native3 = require("react-native");
1129
- var import_jsx_runtime3 = require("react/jsx-runtime");
1625
+ var import_react11 = require("react");
1626
+ var import_react_native4 = require("react-native");
1627
+ var import_jsx_runtime4 = require("react/jsx-runtime");
1130
1628
  function truncateAddress(address, chars = 4) {
1131
1629
  if (address.length <= chars * 2 + 3) return address;
1132
1630
  return `${address.slice(0, chars)}...${address.slice(-chars)}`;
@@ -1144,20 +1642,20 @@ function UserProfileCard({
1144
1642
  memberSince
1145
1643
  }) {
1146
1644
  const t = useDubsTheme();
1147
- const imageUri = (0, import_react10.useMemo)(
1645
+ const imageUri = (0, import_react11.useMemo)(
1148
1646
  () => avatarUrl || `https://api.dicebear.com/9.x/avataaars/png?seed=${walletAddress}&size=128`,
1149
1647
  [avatarUrl, walletAddress]
1150
1648
  );
1151
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native3.View, { style: [styles2.card, { backgroundColor: t.surface, borderColor: t.border }], children: [
1152
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native3.Image, { source: { uri: imageUri }, style: styles2.avatar }),
1153
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native3.View, { style: styles2.info, children: [
1154
- username ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native3.Text, { style: [styles2.username, { color: t.text }], children: username }) : null,
1155
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native3.Text, { style: [styles2.address, { color: t.textMuted }], children: truncateAddress(walletAddress) }),
1156
- memberSince ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native3.Text, { style: [styles2.memberSince, { color: t.textDim }], children: formatMemberSince(memberSince) }) : null
1649
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native4.View, { style: [styles2.card, { backgroundColor: t.surface, borderColor: t.border }], children: [
1650
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.Image, { source: { uri: imageUri }, style: styles2.avatar }),
1651
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native4.View, { style: styles2.info, children: [
1652
+ username ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.Text, { style: [styles2.username, { color: t.text }], children: username }) : null,
1653
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.Text, { style: [styles2.address, { color: t.textMuted }], children: truncateAddress(walletAddress) }),
1654
+ memberSince ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.Text, { style: [styles2.memberSince, { color: t.textDim }], children: formatMemberSince(memberSince) }) : null
1157
1655
  ] })
1158
1656
  ] });
1159
1657
  }
1160
- var styles2 = import_react_native3.StyleSheet.create({
1658
+ var styles2 = import_react_native4.StyleSheet.create({
1161
1659
  card: {
1162
1660
  flexDirection: "row",
1163
1661
  alignItems: "center",
@@ -1191,8 +1689,8 @@ var styles2 = import_react_native3.StyleSheet.create({
1191
1689
  });
1192
1690
 
1193
1691
  // src/ui/SettingsSheet.tsx
1194
- var import_react_native4 = require("react-native");
1195
- var import_jsx_runtime4 = require("react/jsx-runtime");
1692
+ var import_react_native5 = require("react-native");
1693
+ var import_jsx_runtime5 = require("react/jsx-runtime");
1196
1694
  function truncateAddress2(address, chars = 4) {
1197
1695
  if (address.length <= chars * 2 + 3) return address;
1198
1696
  return `${address.slice(0, chars)}...${address.slice(-chars)}`;
@@ -1209,13 +1707,13 @@ function SettingsSheet({
1209
1707
  loggingOut = false
1210
1708
  }) {
1211
1709
  const t = useDubsTheme();
1212
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1213
- import_react_native4.ScrollView,
1710
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1711
+ import_react_native5.ScrollView,
1214
1712
  {
1215
1713
  style: [styles3.container, { backgroundColor: t.background }],
1216
1714
  contentContainerStyle: styles3.content,
1217
1715
  children: [
1218
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1716
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1219
1717
  UserProfileCard,
1220
1718
  {
1221
1719
  walletAddress,
@@ -1224,49 +1722,49 @@ function SettingsSheet({
1224
1722
  memberSince
1225
1723
  }
1226
1724
  ),
1227
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native4.View, { style: [styles3.actionsCard, { backgroundColor: t.surface, borderColor: t.border }], children: [
1228
- onCopyAddress ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1229
- import_react_native4.TouchableOpacity,
1725
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native5.View, { style: [styles3.actionsCard, { backgroundColor: t.surface, borderColor: t.border }], children: [
1726
+ onCopyAddress ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1727
+ import_react_native5.TouchableOpacity,
1230
1728
  {
1231
1729
  style: styles3.actionRow,
1232
1730
  onPress: onCopyAddress,
1233
1731
  activeOpacity: 0.7,
1234
1732
  children: [
1235
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native4.View, { style: styles3.actionRowLeft, children: [
1236
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.Text, { style: [styles3.actionLabel, { color: t.text }], children: "Wallet Address" }),
1237
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.Text, { style: [styles3.actionValue, { color: t.textMuted }], children: truncateAddress2(walletAddress) })
1733
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native5.View, { style: styles3.actionRowLeft, children: [
1734
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native5.Text, { style: [styles3.actionLabel, { color: t.text }], children: "Wallet Address" }),
1735
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native5.Text, { style: [styles3.actionValue, { color: t.textMuted }], children: truncateAddress2(walletAddress) })
1238
1736
  ] }),
1239
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.Text, { style: [styles3.copyLabel, { color: t.accent }], children: "Copy" })
1737
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native5.Text, { style: [styles3.copyLabel, { color: t.accent }], children: "Copy" })
1240
1738
  ]
1241
1739
  }
1242
1740
  ) : null,
1243
- onSupport ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
1244
- onCopyAddress ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.View, { style: [styles3.separator, { backgroundColor: t.border }] }) : null,
1245
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1246
- import_react_native4.TouchableOpacity,
1741
+ onSupport ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1742
+ onCopyAddress ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native5.View, { style: [styles3.separator, { backgroundColor: t.border }] }) : null,
1743
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1744
+ import_react_native5.TouchableOpacity,
1247
1745
  {
1248
1746
  style: styles3.actionRow,
1249
1747
  onPress: onSupport,
1250
1748
  activeOpacity: 0.7,
1251
1749
  children: [
1252
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.Text, { style: [styles3.actionLabel, { color: t.text }], children: "Help & Support" }),
1253
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.Text, { style: [styles3.chevron, { color: t.textMuted }], children: "\u203A" })
1750
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native5.Text, { style: [styles3.actionLabel, { color: t.text }], children: "Help & Support" }),
1751
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native5.Text, { style: [styles3.chevron, { color: t.textMuted }], children: "\u203A" })
1254
1752
  ]
1255
1753
  }
1256
1754
  )
1257
1755
  ] }) : null
1258
1756
  ] }),
1259
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1260
- import_react_native4.TouchableOpacity,
1757
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1758
+ import_react_native5.TouchableOpacity,
1261
1759
  {
1262
1760
  style: [styles3.logoutButton, { borderColor: t.live }],
1263
1761
  onPress: onLogout,
1264
1762
  disabled: loggingOut,
1265
1763
  activeOpacity: 0.7,
1266
- children: loggingOut ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.ActivityIndicator, { color: t.live, size: "small" }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.Text, { style: [styles3.logoutText, { color: t.live }], children: "Log Out" })
1764
+ children: loggingOut ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native5.ActivityIndicator, { color: t.live, size: "small" }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native5.Text, { style: [styles3.logoutText, { color: t.live }], children: "Log Out" })
1267
1765
  }
1268
1766
  ),
1269
- appVersion ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native4.Text, { style: [styles3.version, { color: t.textDim }], children: [
1767
+ appVersion ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native5.Text, { style: [styles3.version, { color: t.textDim }], children: [
1270
1768
  "v",
1271
1769
  appVersion
1272
1770
  ] }) : null
@@ -1274,7 +1772,7 @@ function SettingsSheet({
1274
1772
  }
1275
1773
  );
1276
1774
  }
1277
- var styles3 = import_react_native4.StyleSheet.create({
1775
+ var styles3 = import_react_native5.StyleSheet.create({
1278
1776
  container: {
1279
1777
  flex: 1
1280
1778
  },
@@ -1337,6 +1835,7 @@ var styles3 = import_react_native4.StyleSheet.create({
1337
1835
  });
1338
1836
  // Annotate the CommonJS export names for ESM import in node:
1339
1837
  0 && (module.exports = {
1838
+ AuthGate,
1340
1839
  ConnectWalletScreen,
1341
1840
  DEFAULT_BASE_URL,
1342
1841
  DEFAULT_RPC_URL,