Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,12 @@ NEXT_PUBLIC_RPC_URL=https://soroban-testnet.stellar.org
NEXT_PUBLIC_NETWORK_PASSPHRASE=Test SDF Network ; September 2015
NEXT_PUBLIC_FACTORY_ADDRESS= # output of scripts/deploy_factory.sh

# Indexer & CAP-46 NFT Gallery
NEXT_PUBLIC_WRAITH_URL=https://wraith-0jo1.onrender.com
NEXT_PUBLIC_NFT_FIXTURES=0

# Used by scripts (Node.js — no NEXT_PUBLIC_ prefix)
RPC_URL=https://soroban-testnet.stellar.org
NETWORK_PASSPHRASE=Test SDF Network ; September 2015
FACTORY_ADDRESS= # same value as above

139 changes: 75 additions & 64 deletions frontend/mobile/app/buy.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import React from "react";
import { useCallback, useEffect, useRef, useState } from 'react';
import * as Linking from 'expo-linking';
import * as WebBrowser from 'expo-web-browser';
Expand All @@ -10,6 +11,7 @@ import {
TextInput,
View,
} from 'react-native';
import { Stack } from "expo-router";
import { Keypair } from '@stellar/stellar-sdk';

import {
Expand Down Expand Up @@ -189,6 +191,7 @@ export default function BuyScreen() {
if (step === 'success') {
return (
<View style={styles.container}>
<Stack.Screen options={{ title: "Buy", headerShown: true }} />
<Text style={styles.title}>Deposit confirmed</Text>
<Text style={styles.subtitle}>
Your funds are on their way. It may take a few minutes for the balance to appear.
Expand All @@ -208,6 +211,7 @@ export default function BuyScreen() {
if (step === 'pending') {
return (
<View style={styles.container}>
<Stack.Screen options={{ title: "Buy", headerShown: true }} />
<Text style={styles.title}>Waiting for the anchor</Text>
<Text style={styles.subtitle}>
Complete the deposit in the browser window. Come back here when you&apos;re done.
Expand All @@ -231,6 +235,7 @@ export default function BuyScreen() {

return (
<ScrollView contentContainerStyle={styles.container}>
<Stack.Screen options={{ title: "Buy", headerShown: true }} />
<Text style={styles.title}>Buy</Text>
<Text style={styles.subtitle}>Bring fiat into your wallet through a SEP-24 anchor.</Text>

Expand Down Expand Up @@ -300,122 +305,128 @@ export default function BuyScreen() {

const styles = StyleSheet.create({
container: {
flexGrow: 1,
backgroundColor: '#0B0B0F',
flex: 1,
backgroundColor: '#0f172a',
padding: 24,
gap: 16,
},
title: {
color: '#FFFFFF',
fontSize: 28,
fontWeight: '700',
color: '#f8fafc',
marginBottom: 8,
},
subtitle: {
color: '#9BA1A6',
fontSize: 15,
},
notice: {
backgroundColor: '#1e293b',
borderRadius: 10,
borderWidth: 1,
borderColor: '#334155',
padding: 14,
},
noticeText: {
color: '#94a3b8',
fontSize: 13,
lineHeight: 18,
marginBottom: 32,
lineHeight: 22,
},
form: {
gap: 10,
gap: 16,
},
label: {
color: '#64748b',
fontSize: 11,
fontSize: 12,
fontWeight: '600',
textTransform: 'uppercase',
letterSpacing: 1,
color: '#64748b',
letterSpacing: 0.5,
marginBottom: 6,
},
input: {
backgroundColor: '#1e293b',
borderRadius: 12,
paddingHorizontal: 16,
paddingVertical: 14,
fontSize: 16,
color: '#f8fafc',
borderWidth: 1,
borderColor: '#334155',
},
row: {
flexDirection: 'row',
gap: 10,
gap: 12,
},
rowFieldFlex: {
flex: 2,
gap: 6,
},
rowFieldAsset: {
flex: 1,
gap: 6,
},
input: {
backgroundColor: '#1e293b',
borderRadius: 10,
padding: 14,
color: '#f1f5f9',
fontSize: 16,
borderWidth: 1,
borderColor: '#334155',
rowFieldAsset: {
width: 100,
},
btn: {
borderRadius: 10,
paddingVertical: 14,
borderRadius: 12,
paddingVertical: 16,
alignItems: 'center',
justifyContent: 'center',
marginTop: 8,
},
btnPrimary: {
backgroundColor: '#6366f1',
},
btnSecondary: {
backgroundColor: '#334155',
marginTop: 16,
},
btnDisabled: {
opacity: 0.4,
opacity: 0.6,
},
btnText: {
color: '#fff',
fontSize: 16,
fontWeight: '600',
},
linkBtn: {
alignItems: 'center',
paddingVertical: 8,
error: {
color: '#f87171',
marginTop: 16,
textAlign: 'center',
},
linkText: {
color: '#94a3b8',
notice: {
backgroundColor: '#312e81',
borderRadius: 12,
padding: 16,
marginBottom: 24,
borderLeftWidth: 4,
borderLeftColor: '#818cf8',
},
noticeText: {
color: '#c7d2fe',
fontSize: 14,
lineHeight: 20,
},
card: {
backgroundColor: '#1e293b',
borderRadius: 10,
padding: 14,
gap: 4,
borderRadius: 12,
padding: 16,
marginBottom: 16,
borderWidth: 1,
borderColor: '#334155',
},
rowLabel: {
fontSize: 12,
color: '#64748b',
fontSize: 11,
fontWeight: '600',
textTransform: 'uppercase',
letterSpacing: 1,
marginBottom: 4,
},
rowValue: {
color: '#f1f5f9',
fontSize: 14,
fontWeight: '600',
fontSize: 16,
color: '#f8fafc',
fontWeight: '500',
},
spinner: {
marginVertical: 4,
marginVertical: 24,
},
linkBtn: {
marginTop: 16,
alignItems: 'center',
},
linkText: {
color: '#94a3b8',
fontSize: 15,
},
amount: {
color: '#a5b4fc',
fontFamily: 'monospace',
fontSize: 20,
fontSize: 24,
fontWeight: '700',
},
error: {
color: '#f87171',
fontSize: 13,
backgroundColor: '#450a0a',
borderRadius: 8,
padding: 10,
color: '#34d399',
marginVertical: 16,
textAlign: 'center',
},
});


38 changes: 33 additions & 5 deletions frontend/mobile/app/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { useEffect, useMemo, useRef, useState } from "react";
import { View, ActivityIndicator, StyleSheet } from "react-native";
import { View, ActivityIndicator, StyleSheet, Text } from "react-native";
import { useRouter } from "expo-router";
import AsyncStorage from "@react-native-async-storage/async-storage";

import { useTheme } from "../hooks/useTheme";
import type { ThemeColors } from "../lib/theme";
import { getWalletAddress } from "../lib/walletStore";
import { QuickActions } from "../components/QuickActions";

// Whether the intro has been seen is presentation state, not a secret, so it
// lives in AsyncStorage. The wallet address itself is read through walletStore,
Expand Down Expand Up @@ -39,6 +40,7 @@ export default function Index() {
const styles = useMemo(() => createStyles(colors), [colors]);
const navigated = useRef(false);
const [loading, setLoading] = useState(true);
const [showDashboard, setShowDashboard] = useState(false);

useEffect(() => {
(async () => {
Expand All @@ -48,7 +50,8 @@ export default function Index() {
navigated.current = true;

if (wallet) {
router.replace("/dashboard");
// User has a wallet, show the dashboard instead of redirecting
setShowDashboard(true);
} else if (seenWelcome) {
router.replace("/create-wallet");
} else {
Expand All @@ -62,7 +65,7 @@ export default function Index() {
setLoading(false);
}
})();
}, []);
}, [router]);

if (loading) {
return (
Expand All @@ -72,15 +75,40 @@ export default function Index() {
);
}

// Show the Veil Mobile dashboard when user has a wallet
if (showDashboard) {
return (
<View style={styles.container}>
<Text style={styles.title}>Veil Mobile</Text>
<Text style={styles.subtitle}>Dashboard</Text>
<QuickActions />
</View>
);
}

// This shouldn't normally render as we redirect, but acts as a fallback
return null;
}

const createStyles = (colors: ThemeColors) =>
StyleSheet.create({
function createStyles(colors: ThemeColors) {
return StyleSheet.create({
container: {
flex: 1,
alignItems: "center",
justifyContent: "center",
backgroundColor: colors.background,
padding: 24,
},
title: {
color: colors.textStrong,
fontSize: 24,
fontWeight: "700",
},
subtitle: {
color: colors.textSecondary,
fontSize: 15,
marginTop: 8,
textAlign: "center",
},
});
}
34 changes: 34 additions & 0 deletions frontend/mobile/app/receive.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React from "react";
import { StyleSheet, Text, View } from "react-native";
import { Stack } from "expo-router";

export default function ReceiveScreen() {
return (
<View style={styles.container}>
<Stack.Screen options={{ title: "Receive", headerShown: true }} />
<Text style={styles.title}>Receive</Text>
<Text style={styles.subtitle}>Receive tokens via QR code or address</Text>
</View>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: "center",
justifyContent: "center",
backgroundColor: "#0B0B0F",
padding: 24,
},
title: {
color: "#FFFFFF",
fontSize: 24,
fontWeight: "700",
},
subtitle: {
color: "#9BA1A6",
fontSize: 15,
marginTop: 8,
textAlign: "center",
},
});
34 changes: 34 additions & 0 deletions frontend/mobile/app/send.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React from "react";
import { StyleSheet, Text, View } from "react-native";
import { Stack } from "expo-router";

export default function SendScreen() {
return (
<View style={styles.container}>
<Stack.Screen options={{ title: "Send", headerShown: true }} />
<Text style={styles.title}>Send</Text>
<Text style={styles.subtitle}>Send tokens to another address</Text>
</View>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: "center",
justifyContent: "center",
backgroundColor: "#0B0B0F",
padding: 24,
},
title: {
color: "#FFFFFF",
fontSize: 24,
fontWeight: "700",
},
subtitle: {
color: "#9BA1A6",
fontSize: 15,
marginTop: 8,
textAlign: "center",
},
});
Loading
Loading