@dubsdotapp/expo 0.1.0 → 0.1.2

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,
@@ -973,7 +974,8 @@ function useAuth() {
973
974
  };
974
975
  }
975
976
 
976
- // src/ui/ConnectWalletScreen.tsx
977
+ // src/ui/AuthGate.tsx
978
+ var import_react10 = require("react");
977
979
  var import_react_native2 = require("react-native");
978
980
 
979
981
  // src/ui/theme.ts
@@ -1015,20 +1017,206 @@ function useDubsTheme() {
1015
1017
  return scheme === "light" ? light : dark;
1016
1018
  }
1017
1019
 
1018
- // src/ui/ConnectWalletScreen.tsx
1020
+ // src/ui/AuthGate.tsx
1019
1021
  var import_jsx_runtime2 = require("react/jsx-runtime");
1020
- function ConnectWalletScreen({
1021
- onConnect,
1022
- connecting = false,
1023
- error = null,
1022
+ function AuthGate({
1023
+ children,
1024
+ onSaveToken,
1025
+ onLoadToken,
1026
+ renderLoading,
1027
+ renderError,
1028
+ renderRegistration,
1024
1029
  appName = "Dubs"
1030
+ }) {
1031
+ const { client } = useDubs();
1032
+ const auth = useAuth();
1033
+ const [phase, setPhase] = (0, import_react10.useState)("init");
1034
+ const [registrationPhase, setRegistrationPhase] = (0, import_react10.useState)(false);
1035
+ (0, import_react10.useEffect)(() => {
1036
+ let cancelled = false;
1037
+ (async () => {
1038
+ try {
1039
+ const savedToken = await onLoadToken();
1040
+ if (cancelled) return;
1041
+ if (savedToken) {
1042
+ const restored = await auth.restoreSession(savedToken);
1043
+ if (cancelled) return;
1044
+ if (restored) {
1045
+ setPhase("active");
1046
+ return;
1047
+ }
1048
+ await onSaveToken(null);
1049
+ }
1050
+ if (cancelled) return;
1051
+ setPhase("active");
1052
+ await auth.authenticate();
1053
+ } catch {
1054
+ if (!cancelled) setPhase("active");
1055
+ }
1056
+ })();
1057
+ return () => {
1058
+ cancelled = true;
1059
+ };
1060
+ }, []);
1061
+ (0, import_react10.useEffect)(() => {
1062
+ if (auth.status === "needsRegistration") {
1063
+ setRegistrationPhase(true);
1064
+ }
1065
+ }, [auth.status]);
1066
+ (0, import_react10.useEffect)(() => {
1067
+ if (auth.token) {
1068
+ onSaveToken(auth.token);
1069
+ }
1070
+ }, [auth.token]);
1071
+ const retry = (0, import_react10.useCallback)(() => {
1072
+ setRegistrationPhase(false);
1073
+ auth.reset();
1074
+ auth.authenticate();
1075
+ }, [auth]);
1076
+ const handleRegister = (0, import_react10.useCallback)(
1077
+ (username, referralCode) => {
1078
+ auth.register(username, referralCode);
1079
+ },
1080
+ [auth]
1081
+ );
1082
+ if (phase === "init") {
1083
+ if (renderLoading) return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children: renderLoading("authenticating") });
1084
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DefaultLoadingScreen, { status: "authenticating", appName });
1085
+ }
1086
+ if (auth.status === "authenticated") {
1087
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children });
1088
+ }
1089
+ if (registrationPhase) {
1090
+ const isRegistering = auth.status === "registering";
1091
+ const regError = auth.status === "error" ? auth.error : null;
1092
+ if (renderRegistration) {
1093
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children: renderRegistration({
1094
+ onRegister: handleRegister,
1095
+ registering: isRegistering,
1096
+ error: regError,
1097
+ client
1098
+ }) });
1099
+ }
1100
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1101
+ DefaultRegistrationScreen,
1102
+ {
1103
+ onRegister: handleRegister,
1104
+ registering: isRegistering,
1105
+ error: regError,
1106
+ client,
1107
+ appName
1108
+ }
1109
+ );
1110
+ }
1111
+ if (auth.status === "error" && auth.error) {
1112
+ if (renderError) return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children: renderError(auth.error, retry) });
1113
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DefaultErrorScreen, { error: auth.error, onRetry: retry, appName });
1114
+ }
1115
+ if (renderLoading) return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children: renderLoading(auth.status) });
1116
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DefaultLoadingScreen, { status: auth.status, appName });
1117
+ }
1118
+ function DefaultLoadingScreen({
1119
+ status,
1120
+ appName
1025
1121
  }) {
1026
1122
  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: [
1123
+ const statusText = {
1124
+ idle: "Initializing...",
1125
+ authenticating: "Connecting...",
1126
+ signing: "Approve in your wallet...",
1127
+ verifying: "Verifying...",
1128
+ registering: "Creating account...",
1129
+ needsRegistration: "Almost there...",
1130
+ authenticated: "Ready!",
1131
+ error: "Something went wrong"
1132
+ };
1133
+ 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.centerContent, children: [
1134
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: styles.brandingSection, children: [
1135
+ /* @__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" }) }),
1136
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: [styles.appName, { color: t.text }], children: appName })
1137
+ ] }),
1138
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: styles.loadingSection, children: [
1139
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.ActivityIndicator, { size: "large", color: t.accent }),
1140
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: [styles.statusText, { color: t.textMuted }], children: statusText[status] || "Loading..." })
1141
+ ] })
1142
+ ] }) });
1143
+ }
1144
+ function DefaultErrorScreen({
1145
+ error,
1146
+ onRetry,
1147
+ appName
1148
+ }) {
1149
+ const t = useDubsTheme();
1150
+ 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.spreadContent, children: [
1151
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: styles.brandingSection, children: [
1152
+ /* @__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" }) }),
1153
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: [styles.appName, { color: t.text }], children: appName })
1154
+ ] }),
1155
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: styles.actionSection, children: [
1156
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1157
+ import_react_native2.View,
1158
+ {
1159
+ style: [
1160
+ styles.errorBox,
1161
+ { backgroundColor: t.errorBg, borderColor: t.errorBorder }
1162
+ ],
1163
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: [styles.errorText, { color: t.errorText }], children: error.message })
1164
+ }
1165
+ ),
1166
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1167
+ import_react_native2.TouchableOpacity,
1168
+ {
1169
+ style: [styles.button, { backgroundColor: t.accent }],
1170
+ onPress: onRetry,
1171
+ activeOpacity: 0.8,
1172
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: styles.buttonText, children: "Try Again" })
1173
+ }
1174
+ )
1175
+ ] })
1176
+ ] }) });
1177
+ }
1178
+ function DefaultRegistrationScreen({
1179
+ onRegister,
1180
+ registering,
1181
+ error,
1182
+ client,
1183
+ appName
1184
+ }) {
1185
+ const t = useDubsTheme();
1186
+ const [username, setUsername] = (0, import_react10.useState)("");
1187
+ const [referralCode, setReferralCode] = (0, import_react10.useState)("");
1188
+ const [checking, setChecking] = (0, import_react10.useState)(false);
1189
+ const [availability, setAvailability] = (0, import_react10.useState)(null);
1190
+ const debounceRef = (0, import_react10.useRef)(null);
1191
+ (0, import_react10.useEffect)(() => {
1192
+ if (debounceRef.current) clearTimeout(debounceRef.current);
1193
+ const trimmed = username.trim();
1194
+ if (trimmed.length < 3) {
1195
+ setAvailability(null);
1196
+ setChecking(false);
1197
+ return;
1198
+ }
1199
+ setChecking(true);
1200
+ debounceRef.current = setTimeout(async () => {
1201
+ try {
1202
+ const result = await client.checkUsername(trimmed);
1203
+ setAvailability(result);
1204
+ } catch {
1205
+ setAvailability(null);
1206
+ } finally {
1207
+ setChecking(false);
1208
+ }
1209
+ }, 500);
1210
+ return () => {
1211
+ if (debounceRef.current) clearTimeout(debounceRef.current);
1212
+ };
1213
+ }, [username, client]);
1214
+ const canSubmit = username.trim().length >= 3 && availability?.available === true && !registering && !checking;
1215
+ 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.spreadContent, children: [
1028
1216
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: styles.brandingSection, children: [
1029
1217
  /* @__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
1218
  /* @__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" })
1219
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: [styles.subtitle, { color: t.textMuted }], children: "Choose a username to get started" })
1032
1220
  ] }),
1033
1221
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: styles.actionSection, children: [
1034
1222
  error ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
@@ -1038,24 +1226,215 @@ function ConnectWalletScreen({
1038
1226
  styles.errorBox,
1039
1227
  { backgroundColor: t.errorBg, borderColor: t.errorBorder }
1040
1228
  ],
1041
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: [styles.errorText, { color: t.errorText }], children: error })
1229
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: [styles.errorText, { color: t.errorText }], children: error.message })
1042
1230
  }
1043
1231
  ) : null,
1232
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { children: [
1233
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1234
+ import_react_native2.TextInput,
1235
+ {
1236
+ style: [
1237
+ styles.input,
1238
+ {
1239
+ backgroundColor: t.surface,
1240
+ color: t.text,
1241
+ borderColor: t.border
1242
+ }
1243
+ ],
1244
+ placeholder: "Username",
1245
+ placeholderTextColor: t.textDim,
1246
+ value: username,
1247
+ onChangeText: setUsername,
1248
+ autoCapitalize: "none",
1249
+ autoCorrect: false,
1250
+ editable: !registering
1251
+ }
1252
+ ),
1253
+ checking ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: [styles.availabilityHint, { color: t.textDim }], children: "Checking..." }) : availability ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1254
+ import_react_native2.Text,
1255
+ {
1256
+ style: [
1257
+ styles.availabilityHint,
1258
+ {
1259
+ color: availability.available ? t.success : t.errorText
1260
+ }
1261
+ ],
1262
+ children: availability.available ? "Available!" : availability.reason || "Username taken"
1263
+ }
1264
+ ) : username.trim().length > 0 && username.trim().length < 3 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: [styles.availabilityHint, { color: t.textDim }], children: "At least 3 characters" }) : null
1265
+ ] }),
1266
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1267
+ import_react_native2.TextInput,
1268
+ {
1269
+ style: [
1270
+ styles.input,
1271
+ {
1272
+ backgroundColor: t.surface,
1273
+ color: t.text,
1274
+ borderColor: t.border
1275
+ }
1276
+ ],
1277
+ placeholder: "Referral code (optional)",
1278
+ placeholderTextColor: t.textDim,
1279
+ value: referralCode,
1280
+ onChangeText: setReferralCode,
1281
+ autoCapitalize: "none",
1282
+ autoCorrect: false,
1283
+ editable: !registering
1284
+ }
1285
+ ),
1044
1286
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1045
1287
  import_react_native2.TouchableOpacity,
1046
1288
  {
1047
- style: [styles.connectButton, { backgroundColor: t.accent }],
1289
+ style: [
1290
+ styles.button,
1291
+ { backgroundColor: t.accent, opacity: canSubmit ? 1 : 0.5 }
1292
+ ],
1293
+ onPress: () => {
1294
+ import_react_native2.Keyboard.dismiss();
1295
+ onRegister(username.trim(), referralCode.trim() || void 0);
1296
+ },
1297
+ disabled: !canSubmit,
1298
+ activeOpacity: 0.8,
1299
+ 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: styles.buttonText, children: "Create Account" })
1300
+ }
1301
+ )
1302
+ ] })
1303
+ ] }) });
1304
+ }
1305
+ var styles = import_react_native2.StyleSheet.create({
1306
+ container: {
1307
+ flex: 1,
1308
+ justifyContent: "center"
1309
+ },
1310
+ centerContent: {
1311
+ flex: 1,
1312
+ justifyContent: "center",
1313
+ alignItems: "center",
1314
+ paddingHorizontal: 32,
1315
+ gap: 48
1316
+ },
1317
+ spreadContent: {
1318
+ flex: 1,
1319
+ justifyContent: "space-between",
1320
+ paddingHorizontal: 32,
1321
+ paddingTop: 120,
1322
+ paddingBottom: 80
1323
+ },
1324
+ brandingSection: {
1325
+ alignItems: "center",
1326
+ gap: 12
1327
+ },
1328
+ logoCircle: {
1329
+ width: 80,
1330
+ height: 80,
1331
+ borderRadius: 40,
1332
+ justifyContent: "center",
1333
+ alignItems: "center",
1334
+ marginBottom: 8
1335
+ },
1336
+ logoText: {
1337
+ fontSize: 36,
1338
+ fontWeight: "800",
1339
+ color: "#FFFFFF"
1340
+ },
1341
+ appName: {
1342
+ fontSize: 32,
1343
+ fontWeight: "800"
1344
+ },
1345
+ subtitle: {
1346
+ fontSize: 16,
1347
+ textAlign: "center",
1348
+ lineHeight: 22
1349
+ },
1350
+ loadingSection: {
1351
+ alignItems: "center",
1352
+ gap: 16
1353
+ },
1354
+ statusText: {
1355
+ fontSize: 16,
1356
+ textAlign: "center"
1357
+ },
1358
+ actionSection: {
1359
+ gap: 16
1360
+ },
1361
+ errorBox: {
1362
+ borderWidth: 1,
1363
+ borderRadius: 12,
1364
+ paddingHorizontal: 16,
1365
+ paddingVertical: 12
1366
+ },
1367
+ errorText: {
1368
+ fontSize: 14,
1369
+ textAlign: "center"
1370
+ },
1371
+ input: {
1372
+ height: 56,
1373
+ borderRadius: 16,
1374
+ borderWidth: 1,
1375
+ paddingHorizontal: 16,
1376
+ fontSize: 16
1377
+ },
1378
+ availabilityHint: {
1379
+ fontSize: 13,
1380
+ marginTop: 6,
1381
+ paddingLeft: 4
1382
+ },
1383
+ button: {
1384
+ height: 56,
1385
+ borderRadius: 16,
1386
+ justifyContent: "center",
1387
+ alignItems: "center"
1388
+ },
1389
+ buttonText: {
1390
+ color: "#FFFFFF",
1391
+ fontSize: 18,
1392
+ fontWeight: "700"
1393
+ }
1394
+ });
1395
+
1396
+ // src/ui/ConnectWalletScreen.tsx
1397
+ var import_react_native3 = require("react-native");
1398
+ var import_jsx_runtime3 = require("react/jsx-runtime");
1399
+ function ConnectWalletScreen({
1400
+ onConnect,
1401
+ connecting = false,
1402
+ error = null,
1403
+ appName = "Dubs"
1404
+ }) {
1405
+ const t = useDubsTheme();
1406
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native3.View, { style: [styles2.container, { backgroundColor: t.background }], children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native3.View, { style: styles2.content, children: [
1407
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native3.View, { style: styles2.brandingSection, children: [
1408
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native3.View, { style: [styles2.logoCircle, { backgroundColor: t.accent }], children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native3.Text, { style: styles2.logoText, children: "D" }) }),
1409
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native3.Text, { style: [styles2.appName, { color: t.text }], children: appName }),
1410
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native3.Text, { style: [styles2.subtitle, { color: t.textMuted }], children: "Connect your Solana wallet to get started" })
1411
+ ] }),
1412
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native3.View, { style: styles2.actionSection, children: [
1413
+ error ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1414
+ import_react_native3.View,
1415
+ {
1416
+ style: [
1417
+ styles2.errorBox,
1418
+ { backgroundColor: t.errorBg, borderColor: t.errorBorder }
1419
+ ],
1420
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native3.Text, { style: [styles2.errorText, { color: t.errorText }], children: error })
1421
+ }
1422
+ ) : null,
1423
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1424
+ import_react_native3.TouchableOpacity,
1425
+ {
1426
+ style: [styles2.connectButton, { backgroundColor: t.accent }],
1048
1427
  onPress: onConnect,
1049
1428
  disabled: connecting,
1050
1429
  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" })
1430
+ 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: styles2.connectButtonText, children: "Connect Wallet" })
1052
1431
  }
1053
1432
  ),
1054
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: [styles.hint, { color: t.textDim }], children: "Phantom, Solflare, or any Solana wallet" })
1433
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native3.Text, { style: [styles2.hint, { color: t.textDim }], children: "Phantom, Solflare, or any Solana wallet" })
1055
1434
  ] })
1056
1435
  ] }) });
1057
1436
  }
1058
- var styles = import_react_native2.StyleSheet.create({
1437
+ var styles2 = import_react_native3.StyleSheet.create({
1059
1438
  container: {
1060
1439
  flex: 1,
1061
1440
  justifyContent: "center"
@@ -1124,9 +1503,9 @@ var styles = import_react_native2.StyleSheet.create({
1124
1503
  });
1125
1504
 
1126
1505
  // 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");
1506
+ var import_react11 = require("react");
1507
+ var import_react_native4 = require("react-native");
1508
+ var import_jsx_runtime4 = require("react/jsx-runtime");
1130
1509
  function truncateAddress(address, chars = 4) {
1131
1510
  if (address.length <= chars * 2 + 3) return address;
1132
1511
  return `${address.slice(0, chars)}...${address.slice(-chars)}`;
@@ -1144,20 +1523,20 @@ function UserProfileCard({
1144
1523
  memberSince
1145
1524
  }) {
1146
1525
  const t = useDubsTheme();
1147
- const imageUri = (0, import_react10.useMemo)(
1526
+ const imageUri = (0, import_react11.useMemo)(
1148
1527
  () => avatarUrl || `https://api.dicebear.com/9.x/avataaars/png?seed=${walletAddress}&size=128`,
1149
1528
  [avatarUrl, walletAddress]
1150
1529
  );
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
1530
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native4.View, { style: [styles3.card, { backgroundColor: t.surface, borderColor: t.border }], children: [
1531
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.Image, { source: { uri: imageUri }, style: styles3.avatar }),
1532
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native4.View, { style: styles3.info, children: [
1533
+ username ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.Text, { style: [styles3.username, { color: t.text }], children: username }) : null,
1534
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.Text, { style: [styles3.address, { color: t.textMuted }], children: truncateAddress(walletAddress) }),
1535
+ memberSince ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.Text, { style: [styles3.memberSince, { color: t.textDim }], children: formatMemberSince(memberSince) }) : null
1157
1536
  ] })
1158
1537
  ] });
1159
1538
  }
1160
- var styles2 = import_react_native3.StyleSheet.create({
1539
+ var styles3 = import_react_native4.StyleSheet.create({
1161
1540
  card: {
1162
1541
  flexDirection: "row",
1163
1542
  alignItems: "center",
@@ -1191,8 +1570,8 @@ var styles2 = import_react_native3.StyleSheet.create({
1191
1570
  });
1192
1571
 
1193
1572
  // src/ui/SettingsSheet.tsx
1194
- var import_react_native4 = require("react-native");
1195
- var import_jsx_runtime4 = require("react/jsx-runtime");
1573
+ var import_react_native5 = require("react-native");
1574
+ var import_jsx_runtime5 = require("react/jsx-runtime");
1196
1575
  function truncateAddress2(address, chars = 4) {
1197
1576
  if (address.length <= chars * 2 + 3) return address;
1198
1577
  return `${address.slice(0, chars)}...${address.slice(-chars)}`;
@@ -1209,13 +1588,13 @@ function SettingsSheet({
1209
1588
  loggingOut = false
1210
1589
  }) {
1211
1590
  const t = useDubsTheme();
1212
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1213
- import_react_native4.ScrollView,
1591
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1592
+ import_react_native5.ScrollView,
1214
1593
  {
1215
- style: [styles3.container, { backgroundColor: t.background }],
1216
- contentContainerStyle: styles3.content,
1594
+ style: [styles4.container, { backgroundColor: t.background }],
1595
+ contentContainerStyle: styles4.content,
1217
1596
  children: [
1218
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1597
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1219
1598
  UserProfileCard,
1220
1599
  {
1221
1600
  walletAddress,
@@ -1224,49 +1603,49 @@ function SettingsSheet({
1224
1603
  memberSince
1225
1604
  }
1226
1605
  ),
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,
1606
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native5.View, { style: [styles4.actionsCard, { backgroundColor: t.surface, borderColor: t.border }], children: [
1607
+ onCopyAddress ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1608
+ import_react_native5.TouchableOpacity,
1230
1609
  {
1231
- style: styles3.actionRow,
1610
+ style: styles4.actionRow,
1232
1611
  onPress: onCopyAddress,
1233
1612
  activeOpacity: 0.7,
1234
1613
  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) })
1614
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native5.View, { style: styles4.actionRowLeft, children: [
1615
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native5.Text, { style: [styles4.actionLabel, { color: t.text }], children: "Wallet Address" }),
1616
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native5.Text, { style: [styles4.actionValue, { color: t.textMuted }], children: truncateAddress2(walletAddress) })
1238
1617
  ] }),
1239
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.Text, { style: [styles3.copyLabel, { color: t.accent }], children: "Copy" })
1618
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native5.Text, { style: [styles4.copyLabel, { color: t.accent }], children: "Copy" })
1240
1619
  ]
1241
1620
  }
1242
1621
  ) : 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,
1622
+ onSupport ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1623
+ onCopyAddress ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native5.View, { style: [styles4.separator, { backgroundColor: t.border }] }) : null,
1624
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1625
+ import_react_native5.TouchableOpacity,
1247
1626
  {
1248
- style: styles3.actionRow,
1627
+ style: styles4.actionRow,
1249
1628
  onPress: onSupport,
1250
1629
  activeOpacity: 0.7,
1251
1630
  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" })
1631
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native5.Text, { style: [styles4.actionLabel, { color: t.text }], children: "Help & Support" }),
1632
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native5.Text, { style: [styles4.chevron, { color: t.textMuted }], children: "\u203A" })
1254
1633
  ]
1255
1634
  }
1256
1635
  )
1257
1636
  ] }) : null
1258
1637
  ] }),
1259
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1260
- import_react_native4.TouchableOpacity,
1638
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1639
+ import_react_native5.TouchableOpacity,
1261
1640
  {
1262
- style: [styles3.logoutButton, { borderColor: t.live }],
1641
+ style: [styles4.logoutButton, { borderColor: t.live }],
1263
1642
  onPress: onLogout,
1264
1643
  disabled: loggingOut,
1265
1644
  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" })
1645
+ 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: [styles4.logoutText, { color: t.live }], children: "Log Out" })
1267
1646
  }
1268
1647
  ),
1269
- appVersion ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native4.Text, { style: [styles3.version, { color: t.textDim }], children: [
1648
+ appVersion ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native5.Text, { style: [styles4.version, { color: t.textDim }], children: [
1270
1649
  "v",
1271
1650
  appVersion
1272
1651
  ] }) : null
@@ -1274,7 +1653,7 @@ function SettingsSheet({
1274
1653
  }
1275
1654
  );
1276
1655
  }
1277
- var styles3 = import_react_native4.StyleSheet.create({
1656
+ var styles4 = import_react_native5.StyleSheet.create({
1278
1657
  container: {
1279
1658
  flex: 1
1280
1659
  },
@@ -1337,6 +1716,7 @@ var styles3 = import_react_native4.StyleSheet.create({
1337
1716
  });
1338
1717
  // Annotate the CommonJS export names for ESM import in node:
1339
1718
  0 && (module.exports = {
1719
+ AuthGate,
1340
1720
  ConnectWalletScreen,
1341
1721
  DEFAULT_BASE_URL,
1342
1722
  DEFAULT_RPC_URL,