diff --git a/wallet_app/app/.gitignore b/wallet_app/app/.gitignore index 591843f0..3449035b 100644 --- a/wallet_app/app/.gitignore +++ b/wallet_app/app/.gitignore @@ -1,2 +1,3 @@ android/app/build -build \ No newline at end of file +build +local.properties \ No newline at end of file diff --git a/wallet_app/app/build.gradle.kts b/wallet_app/app/build.gradle.kts index 76dd788d..28eef37c 100644 --- a/wallet_app/app/build.gradle.kts +++ b/wallet_app/app/build.gradle.kts @@ -104,6 +104,8 @@ dependencies { // Material Design 3 implementation(libs.androidx.material3) + implementation("com.google.android.material:material:1.11.0") + // Retrofit for network requests implementation(libs.retrofit) implementation(libs.converter.gson) diff --git a/wallet_app/app/src/main/java/com/example/walletapp/db/TokenDatabase.kt b/wallet_app/app/src/main/java/com/example/walletapp/db/TokenDatabase.kt index ec84a265..790abd03 100644 --- a/wallet_app/app/src/main/java/com/example/walletapp/db/TokenDatabase.kt +++ b/wallet_app/app/src/main/java/com/example/walletapp/db/TokenDatabase.kt @@ -5,6 +5,7 @@ import androidx.room.Database import androidx.room.Room import androidx.room.RoomDatabase import androidx.room.TypeConverters +import androidx.room.migration.Migration import androidx.sqlite.db.SupportSQLiteDatabase import com.example.walletapp.model.Token import com.example.walletapp.utils.Converters @@ -19,10 +20,28 @@ abstract class TokenDatabase : RoomDatabase() { abstract fun tokenDao(): TokenDao + + companion object { @Volatile private var INSTANCE: TokenDatabase? = null + val MIGRATION_1_2 = object : Migration(1, 2) { + override fun migrate(database: SupportSQLiteDatabase) { + // Create the Token table if it is new + database.execSQL( + """ + CREATE TABLE IF NOT EXISTS Token ( + contactAddress TEXT NOT NULL PRIMARY KEY, + name TEXT NOT NULL, + symbol TEXT NOT NULL, + decimals INTEGER NOT NULL, + tokenId TEXT NOT NULL + ) + """.trimIndent() + ) + } + } fun getDatabase(context: Context): TokenDatabase { return INSTANCE ?: synchronized(this) { val instance = Room.databaseBuilder( @@ -30,7 +49,8 @@ abstract class TokenDatabase : RoomDatabase() { TokenDatabase::class.java, "token_database" ) - .addCallback(DatabaseCallback()) // Add callback here + .addCallback(DatabaseCallback()) + .addMigrations(MIGRATION_1_2) .build() INSTANCE = instance instance @@ -38,6 +58,7 @@ abstract class TokenDatabase : RoomDatabase() { } } + private class DatabaseCallback : RoomDatabase.Callback() { override fun onCreate(db: SupportSQLiteDatabase) { super.onCreate(db) diff --git a/wallet_app/app/src/main/java/com/example/walletapp/ui/WalletApp.kt b/wallet_app/app/src/main/java/com/example/walletapp/ui/WalletApp.kt index 1cb97596..51b4ed26 100644 --- a/wallet_app/app/src/main/java/com/example/walletapp/ui/WalletApp.kt +++ b/wallet_app/app/src/main/java/com/example/walletapp/ui/WalletApp.kt @@ -106,16 +106,16 @@ fun WalletApp(tokenViewModel: TokenViewModel) { composable { AddTokenScreen( tokenViewModel=tokenViewModel, - navController: navController, - onConfirm = { navController.navigateUp() } + onConfirm = { navController.navigateUp() }, + navController ) } composable { - SendScreen(walletViewModel) + SendScreen(walletViewModel,navController) } composable { - ReceiveScreen(modifier = Modifier) + ReceiveScreen(modifier = Modifier,navController) } } } diff --git a/wallet_app/app/src/main/java/com/example/walletapp/ui/account/AddTokenScreen.kt b/wallet_app/app/src/main/java/com/example/walletapp/ui/account/AddTokenScreen.kt index be817f5e..e3de6001 100644 --- a/wallet_app/app/src/main/java/com/example/walletapp/ui/account/AddTokenScreen.kt +++ b/wallet_app/app/src/main/java/com/example/walletapp/ui/account/AddTokenScreen.kt @@ -10,18 +10,12 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.Button -import androidx.compose.material.ButtonDefaults -import androidx.compose.material.Icon -import androidx.compose.material.IconButton -import androidx.compose.material.Surface -import androidx.compose.material.Text -import androidx.compose.material.TextField -import androidx.compose.material.TextFieldDefaults import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ArrowBack import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton import androidx.compose.material3.OutlinedTextFieldDefaults import androidx.compose.material3.Surface import androidx.compose.material3.Text diff --git a/wallet_app/app/src/main/java/com/example/walletapp/ui/account/WalletScreen.kt b/wallet_app/app/src/main/java/com/example/walletapp/ui/account/WalletScreen.kt index 6f63522e..b8d77a66 100644 --- a/wallet_app/app/src/main/java/com/example/walletapp/ui/account/WalletScreen.kt +++ b/wallet_app/app/src/main/java/com/example/walletapp/ui/account/WalletScreen.kt @@ -2,13 +2,12 @@ package com.example.walletapp.ui.account import android.annotation.SuppressLint import android.app.Activity -import android.util.Log +import androidx.compose.ui.platform.ClipboardManager import android.widget.Toast import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row @@ -27,7 +26,6 @@ import androidx.compose.material3.Card import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext @@ -45,12 +43,15 @@ import androidx.compose.runtime.* import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.painter.Painter +import androidx.compose.ui.platform.ClipEntry import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.platform.LocalClipboardManager import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.text.toLowerCase +import android.content.ClipData +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.ui.Alignment import androidx.compose.ui.text.toUpperCase import androidx.compose.ui.window.Popup import androidx.compose.ui.window.PopupProperties @@ -108,6 +109,8 @@ fun Wallet(modifier: Modifier, onNewTokenPress: () -> Unit, onReceivePress: () - val address= BuildConfig.ACCOUNT_ADDRESS val accountAddress = Felt.fromHex(address) + + val clipboard: ClipboardManager = LocalClipboardManager.current var tokenImages by rememberSaveable { mutableStateOf>(hashMapOf()) } val balances by walletViewModel.balances.collectAsState() val coinsPrices by rememberSaveable { mutableStateOf>(hashMapOf()) } @@ -171,22 +174,40 @@ fun Wallet(modifier: Modifier, onNewTokenPress: () -> Unit, onReceivePress: () - }.sum() val formatter = NumberFormat.getCurrencyInstance(Locale.US) - Text( - text = formatter.format(totalBalance), - fontFamily = FontFamily(Font(R.font.publicsans_bold)), - color = Color.White, - fontSize = 24.sp, - modifier = Modifier - .align(Alignment.CenterHorizontally) - .padding(top = 70.dp) - ) - Text( - text = address.take(10) + ".....", - fontFamily = FontFamily(Font(R.font.inter_regular)), - color = Color.White, - fontSize = 14.sp, - modifier = Modifier.align(Alignment.CenterHorizontally) - ) + Column(verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.fillMaxWidth()) { + Text( + text = formatter.format(totalBalance), + fontFamily = FontFamily(Font(R.font.publicsans_bold)), + color = Color.White, + fontSize = 26.sp, + modifier = Modifier + .align(Alignment.CenterHorizontally) + .padding(top = 70.dp) + ) + Row( + modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Center + ) { + Text( + text = address.take(8) + "...", + fontFamily = FontFamily(Font(R.font.inter_regular)), + color = Color.White, + fontSize = 12.sp, + ) + Icon( + painter = painterResource(R.drawable.copy),// replace with your Ethereum icon + contentDescription = null, + tint = Color.White, + modifier = Modifier.padding(start = 5.dp) + .size(15.dp).clickable { + val clip = ClipEntry(ClipData.newPlainText("Wallet Address", address)) + clipboard.setClip(clip) + Toast.makeText(context, "Address Copied", Toast.LENGTH_LONG).show() + } + ) + + } + } + Spacer(modifier = Modifier.height(32.dp)) val configuration = LocalConfiguration.current val screenHeight = configuration.screenHeightDp.dp/2 diff --git a/wallet_app/app/src/main/java/com/example/walletapp/ui/onboarding/CreateAccountScreen.kt b/wallet_app/app/src/main/java/com/example/walletapp/ui/onboarding/CreateAccountScreen.kt index 8f39553f..3656c184 100644 --- a/wallet_app/app/src/main/java/com/example/walletapp/ui/onboarding/CreateAccountScreen.kt +++ b/wallet_app/app/src/main/java/com/example/walletapp/ui/onboarding/CreateAccountScreen.kt @@ -64,11 +64,6 @@ fun CreateAccountScreen( var progress by remember { mutableStateOf(0.5f) } Scaffold( topBar = { - TopAppBar( - backgroundColor = Color("#0C0C4F".toColorInt()), - contentColor = Color.White, - elevation = 4.dp - ) { Row( modifier = Modifier .fillMaxWidth() @@ -97,22 +92,8 @@ fun CreateAccountScreen( } - } + } - title = { Text("Create Account", color = Color.White, fontSize = 20.sp) }, - navigationIcon = { - Icon( - imageVector = Icons.Filled.ArrowBack, - contentDescription = "Backward Arrow", - modifier = Modifier.padding(start = 8.dp), - tint = Color.White - ) - }, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = Color("#0C0C4F".toColorInt()), - titleContentColor = Color.White - ) - ) } ) { paddingValues -> Column( @@ -386,4 +367,3 @@ fun GeneratekeySheet( } - diff --git a/wallet_app/app/src/main/java/com/example/walletapp/ui/onboarding/FinalizeAccountCreationScreen.kt b/wallet_app/app/src/main/java/com/example/walletapp/ui/onboarding/FinalizeAccountCreationScreen.kt index a0dedd29..91d43ba9 100644 --- a/wallet_app/app/src/main/java/com/example/walletapp/ui/onboarding/FinalizeAccountCreationScreen.kt +++ b/wallet_app/app/src/main/java/com/example/walletapp/ui/onboarding/FinalizeAccountCreationScreen.kt @@ -41,11 +41,6 @@ fun FinalizeAccountCreationScreen( ) { Scaffold( topBar = { - TopAppBar( - backgroundColor = Color("#0C0C4F".toColorInt()), - contentColor = Color.White, - elevation = 4.dp - ) { Row( modifier = Modifier .fillMaxWidth() @@ -76,21 +71,6 @@ fun FinalizeAccountCreationScreen( } } - title = { Text("Create Account", color = Color.White, fontSize = 20.sp) }, - navigationIcon = { - Icon( - imageVector = Icons.Filled.ArrowBack, - contentDescription = "Backward Arrow", - modifier = Modifier.padding(start = 8.dp), - tint = Color.White - ) - }, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = Color("#0C0C4F".toColorInt()), - titleContentColor = Color.White - ) - ) - } ) { paddingValues -> Column( modifier = Modifier diff --git a/wallet_app/app/src/main/java/com/example/walletapp/ui/onboarding/ImportAccountScreen.kt b/wallet_app/app/src/main/java/com/example/walletapp/ui/onboarding/ImportAccountScreen.kt index 634b8c72..a996ad7f 100644 --- a/wallet_app/app/src/main/java/com/example/walletapp/ui/onboarding/ImportAccountScreen.kt +++ b/wallet_app/app/src/main/java/com/example/walletapp/ui/onboarding/ImportAccountScreen.kt @@ -60,15 +60,9 @@ fun ImportAccountScreen( onFinishAccountImport: () -> Unit, onBackButtonPressed: () -> Unit ) { -fun ImportAccountScreen(onFinishAccountImport: () -> Unit) { var progress by remember { mutableStateOf(0.5f) } Scaffold( topBar = { - TopAppBar( - backgroundColor = Color("#0C0C4F".toColorInt()), - contentColor = Color.White, - elevation = 4.dp - ) { Row( modifier = Modifier .fillMaxWidth() @@ -99,21 +93,6 @@ fun ImportAccountScreen(onFinishAccountImport: () -> Unit) { } } - title = { Text("Import existing wallet", color = Color.White, fontSize = 20.sp) }, - navigationIcon = { - Icon( - imageVector = Icons.Filled.ArrowBack, - contentDescription = "Backward Arrow", - modifier = Modifier.padding(start = 8.dp), - tint = Color.White - ) - }, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = Color("#0C0C4F".toColorInt()), - titleContentColor = Color.White - ) - ) - } ) { paddingValues -> Column( modifier = Modifier diff --git a/wallet_app/app/src/main/java/com/example/walletapp/ui/transfer/ReceiveScreen.kt b/wallet_app/app/src/main/java/com/example/walletapp/ui/transfer/ReceiveScreen.kt index 13ce2665..63f7615a 100644 --- a/wallet_app/app/src/main/java/com/example/walletapp/ui/transfer/ReceiveScreen.kt +++ b/wallet_app/app/src/main/java/com/example/walletapp/ui/transfer/ReceiveScreen.kt @@ -1,17 +1,24 @@ package com.example.walletapp.ui.transfer import android.content.ClipData +import android.widget.Toast import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.ArrowBack +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -21,17 +28,22 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.ClipEntry import androidx.compose.ui.platform.ClipboardManager import androidx.compose.ui.platform.LocalClipboardManager +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.font.Font import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.core.graphics.toColorInt +import androidx.navigation.NavController +import com.example.walletapp.BuildConfig import com.example.walletapp.R @Composable -fun ReceiveScreen(modifier: Modifier) { +fun ReceiveScreen(modifier: Modifier,navController: NavController) { val clipboard: ClipboardManager = LocalClipboardManager.current + val context= LocalContext.current + val address= BuildConfig.ACCOUNT_ADDRESS Surface(modifier = Modifier.fillMaxSize()) { Column( @@ -40,8 +52,19 @@ fun ReceiveScreen(modifier: Modifier) { .background(Color("#0C0C4F".toColorInt())) // Your dark blue background color .padding(16.dp), horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Center ) { + // Back Button + IconButton( + onClick = { navController.navigateUp() }, + modifier = Modifier.align(Alignment.Start) + ) { + Icon( + imageVector = Icons.Default.ArrowBack, + contentDescription = "Back", + tint = Color.White + ) + } + Spacer(modifier = Modifier.height(40.dp)) // QR Code Image Box( modifier = Modifier @@ -57,27 +80,27 @@ fun ReceiveScreen(modifier: Modifier) { Spacer(modifier = Modifier.height(24.dp)) - // Wallet Address - Text( - text = "0xfoo...123", // Replace with actual wallet address - fontFamily = FontFamily(Font(R.font.publicsans_bold)), - color = Color.White, - fontSize = 40.sp - ) - Spacer(modifier = Modifier.height(8.dp)) + Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Center) { + Text( + text = address.take(8) + "...", + fontFamily = FontFamily(Font(R.font.publicsans_bold)), + color = Color.White, + fontSize = 30.sp + ) + Icon( + painter = painterResource(R.drawable.copy),// replace with your Ethereum icon + contentDescription = null, + tint=Color.White, + modifier = Modifier.padding(start=5.dp) + .size(25.dp).clickable { + val clip = ClipEntry(ClipData.newPlainText("Wallet Address", address)) + clipboard.setClip(clip) + Toast.makeText(context, "Address Copied", Toast.LENGTH_LONG).show() + } + ) - // Clickable Text for Copy - Text( - text = "Click to copy address", - fontFamily = FontFamily(Font(R.font.publicsans_regular)), - color = Color.White, - fontSize = 15.sp, - modifier = Modifier.clickable { - val clip = ClipEntry(ClipData.newPlainText("Wallet Address", "0xfoo...123")) // TODO: Replace with actual wallet address - clipboard.setClip(clip) - } - ) + } } } diff --git a/wallet_app/app/src/main/java/com/example/walletapp/ui/transfer/SendScreen.kt b/wallet_app/app/src/main/java/com/example/walletapp/ui/transfer/SendScreen.kt index c2b95ec4..e8d6a2c8 100644 --- a/wallet_app/app/src/main/java/com/example/walletapp/ui/transfer/SendScreen.kt +++ b/wallet_app/app/src/main/java/com/example/walletapp/ui/transfer/SendScreen.kt @@ -44,12 +44,15 @@ import com.example.walletapp.R import com.example.walletapp.ui.account.WalletViewModel import android.widget.Toast import androidx.compose.foundation.layout.Box -import androidx.compose.material.DropdownMenuItem +import androidx.compose.material.icons.filled.ArrowBack import androidx.compose.material3.DropdownMenu +import androidx.compose.material3.DropdownMenuItem +import androidx.compose.material3.IconButton import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.remember import androidx.compose.ui.platform.LocalContext +import androidx.navigation.NavController import com.example.walletapp.utils.etherToWei import com.example.walletapp.utils.isValidEthereumAddress import com.swmansion.starknet.account.StandardAccount @@ -63,7 +66,7 @@ import java.math.BigDecimal @Composable -fun SendScreen(walletViewModel: WalletViewModel) { +fun SendScreen(walletViewModel: WalletViewModel,navController: NavController) { val balances by walletViewModel.balances.collectAsState() val address= BuildConfig.ACCOUNT_ADDRESS @@ -143,6 +146,17 @@ fun SendScreen(walletViewModel: WalletViewModel) { horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center ) { + // Back Button + IconButton( + onClick = { navController.navigateUp() }, + modifier = Modifier.align(Alignment.Start) + ) { + Icon( + imageVector = Icons.Default.ArrowBack, + contentDescription = "Back", + tint = Color.White + ) + } Spacer(modifier = Modifier.height(40.dp)) // "From" label above the wallet address field (readonly) @@ -306,27 +320,33 @@ fun TokenDropdown( DropdownMenuItem(onClick = { onTokenSelected("ethereum") expanded = false - }) { - Image( - painter = painterResource(id = R.drawable.ic_ethereum), - contentDescription = null, - modifier = Modifier.size(24.dp) - ) - Spacer(modifier = Modifier.width(8.dp)) - Text("ETH", color = Color.White) - } + }, + leadingIcon = { + Image( + painter = painterResource(id = R.drawable.ic_ethereum), + contentDescription = null, + modifier = Modifier.size(24.dp) + ) + + }, + text={ + Text("ETH", color = Color.White) + }) DropdownMenuItem(onClick = { onTokenSelected("starknet") expanded = false - }) { - Image( - painter = painterResource(id = R.drawable.starknet_icon), - contentDescription = null, - modifier = Modifier.size(24.dp) - ) - Spacer(modifier = Modifier.width(8.dp)) - Text("STRK", color = Color.White) - } + }, + leadingIcon = { + Image( + painter = painterResource(id = R.drawable.starknet_icon), + contentDescription = null, + modifier = Modifier.size(24.dp) + ) + + }, + text={ + Text("STRK", color = Color.White) + }) } } } diff --git a/wallet_app/app/src/main/res/drawable/copy.png b/wallet_app/app/src/main/res/drawable/copy.png index c2198fe6..562a13c3 100644 Binary files a/wallet_app/app/src/main/res/drawable/copy.png and b/wallet_app/app/src/main/res/drawable/copy.png differ diff --git a/wallet_app/local.properties b/wallet_app/local.properties deleted file mode 100644 index 9e09d72f..00000000 --- a/wallet_app/local.properties +++ /dev/null @@ -1,11 +0,0 @@ -## This file must *NOT* be checked into Version Control Systems, -# as it contains information specific to your local configuration. -# -# Location of the SDK. This is only used by Gradle. -# For customization when using a Version Control System, please read the -# header note. -#Sun Oct 06 17:45:21 CDT 2024 -ACCOUNT_ADDRESS=0x06b06423feba3e1a345095699c59430e936c5413699ff9ef8ec8a6dbefdab1f1 -KEY_NAME= -RPC_URL=https://starknet-mainnet.g.alchemy.com/starknet/version/rpc/v0_7/Fl4zNtN2hak5hrWq92a8pnB-ZospWX9a -sdk.dir=/home/thomas/Android/Sdk