Skip to content
Merged
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
19 changes: 19 additions & 0 deletions Variant — 0.30/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
*.iml
.gradle
/.idea/
.DS_Store
/build
/app/build/
/captures
.externalNativeBuild
.cxx
app-simple-wallet/local.properties
app-advanced-features/local.properties
app-ui-only/local.properties
app-simple-wallet/app/build/
app/build/
app-ui-only/app/build/
app-clean/
.idea/
local.properties
app.run.xml
81 changes: 81 additions & 0 deletions Variant — 0.30/app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
}

android {
compileSdk = 34

buildFeatures {
viewBinding = true
compose = true
}

defaultConfig {
applicationId = "com.goldenraven.devkitwallet"
minSdk = 26
targetSdk = 34
versionCode = 1
versionName = "v0.0.1"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}

buildTypes {
getByName("debug") {
isDebuggable = true
}
}

compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}

kotlinOptions {
jvmTarget = "1.8"
}

composeOptions {
kotlinCompilerExtensionVersion = "1.5.5"
}

namespace = "com.goldenraven.devkitwallet"
}

dependencies {
// basic android dependencies
implementation ("org.jetbrains.kotlin:kotlin-stdlib:1.9.20")
implementation ("androidx.core:core-ktx:1.12.0")
implementation ("com.google.android.material:material:1.10.0")

// compose
// Adding the Bill of Materials synchronizes dependencies in the androidx.compose namespace
// You can remove the library version in your dependency declarations
implementation(platform("androidx.compose:compose-bom:2023.06.01"))
implementation("androidx.compose.material:material")
implementation("androidx.compose.animation:animation")
implementation("androidx.compose.ui:ui-tooling")
implementation("androidx.compose.runtime:runtime-livedata")
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.material3:material3")
implementation("androidx.activity:activity-compose")
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.2")
// implementation("androidx.navigation:navigation-compose:2.4.1")
implementation("androidx.constraintlayout:constraintlayout-compose:1.0.1")
implementation("com.google.accompanist:accompanist-navigation-animation:0.23.1")
implementation("com.google.accompanist:accompanist-systemuicontroller:0.23.1")

// toolbar
implementation("androidx.appcompat:appcompat:1.6.1")

// bitcoindevkit
implementation("org.bitcoindevkit:bdk-android:0.30.0")

// qr codes
implementation("com.google.zxing:core:3.4.1")

// tests
testImplementation ("junit:junit:4.13.2")
androidTestImplementation ("androidx.test.ext:junit:1.1.5")
androidTestImplementation ("androidx.test.espresso:espresso-core:3.5.1")
}
File renamed without changes.
28 changes: 28 additions & 0 deletions Variant — 0.30/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android">

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:name=".DevkitWalletApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_bdk_round"
android:supportsRtl="true"
android:theme="@style/Theme.BitcoindevkitSampleApp">

<activity
android:name="com.goldenraven.devkitwallet.DevkitWalletActivity"
android:theme="@style/Theme.BitcoindevkitSampleApp.Launcher"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Copyright 2021-2023 thunderbiscuit and contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the ./LICENSE file.
*/

package com.goldenraven.devkitwallet

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import androidx.activity.compose.setContent
import com.goldenraven.devkitwallet.domain.Repository
import com.goldenraven.devkitwallet.domain.Wallet
import com.goldenraven.devkitwallet.navigation.HomeNavigation
import com.goldenraven.devkitwallet.navigation.CreateWalletNavigation
import com.goldenraven.devkitwallet.ui.theme.DevkitTheme

private const val TAG = "DevkitWalletActivity"

class DevkitWalletActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

val onBuildWalletButtonClicked: (WalletCreateType) -> Unit = { walletCreateType ->
try {
// load up a wallet either from scratch or using a BIP39 recovery phrase
when (walletCreateType) {
// if we create a wallet from scratch we don't need a recovery phrase
is WalletCreateType.FROMSCRATCH -> Wallet.createWallet()

is WalletCreateType.RECOVER -> Wallet.recoverWallet(walletCreateType.recoveryPhrase)
}
setContent {
DevkitTheme {
HomeNavigation()
}
}
} catch(e: Throwable) {
Log.i(TAG, "Could not build wallet: $e")
}
}

if (Repository.doesWalletExist()) {
Wallet.loadExistingWallet()
setContent {
DevkitTheme {
HomeNavigation()
}
}
} else {
setContent {
DevkitTheme {
CreateWalletNavigation(onBuildWalletButtonClicked)
}
}
}
}
}

sealed class WalletCreateType {
object FROMSCRATCH : WalletCreateType()
class RECOVER(val recoveryPhrase: String) : WalletCreateType()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright 2021 thunderbiscuit and contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the ./LICENSE file.
*/

package com.goldenraven.devkitwallet

import android.app.Application
import android.content.Context
import com.goldenraven.devkitwallet.utils.SharedPreferencesManager
import com.goldenraven.devkitwallet.domain.Repository
import com.goldenraven.devkitwallet.domain.Wallet

class DevkitWalletApplication : Application() {
override fun onCreate() {
super.onCreate()

// initialize Wallet object (singleton) with path variable
Wallet.setPath(applicationContext.filesDir.toString())

// initialize shared preferences manager object (singleton)
val sharedPreferencesManager = SharedPreferencesManager(
sharedPreferences = applicationContext.getSharedPreferences("current_wallet", Context.MODE_PRIVATE)
)

// initialize Repository object with shared preferences
Repository.setSharedPreferences(sharedPreferencesManager)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Copyright 2021-2023 thunderbiscuit and contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the ./LICENSE file.
*/

package com.goldenraven.devkitwallet.domain

import android.util.Log
import org.bitcoindevkit.Blockchain
import org.bitcoindevkit.BlockchainConfig
import org.bitcoindevkit.ElectrumConfig

private const val TAG = "ElectrumServer"

class ElectrumServer {
private var useDefaultElectrum: Boolean = true
private var default: Blockchain
private var custom: Blockchain? = null
private var customElectrumURL: String
private val defaultElectrumURL = "ssl://electrum.blockstream.info:60002"

init {
val blockchainConfig = BlockchainConfig.Electrum(ElectrumConfig(
url = defaultElectrumURL,
socks5 = null,
retry = 5u,
timeout = null,
stopGap = 10u,
validateDomain = true
))
customElectrumURL = ""
default = Blockchain(blockchainConfig)
}

val server: Blockchain
get() = if (useDefaultElectrum) this.default else this.custom!!

// if you're looking to test different public Electrum servers we recommend these 3:
// ssl://electrum.blockstream.info:60002
// tcp://electrum.blockstream.info:60001
// tcp://testnet.aranguren.org:51001
fun createCustomElectrum(electrumURL: String) {
customElectrumURL = electrumURL
val blockchainConfig = BlockchainConfig.Electrum(ElectrumConfig(
url = customElectrumURL,
socks5 = null,
retry = 5u,
timeout = null,
stopGap = 10u,
validateDomain = true
))
custom = Blockchain(blockchainConfig)
useCustomElectrum()
Log.i(TAG, "New Electrum Server URL : $customElectrumURL")
}

fun useCustomElectrum() {
useDefaultElectrum = false
}

fun useDefaultElectrum() {
useDefaultElectrum = true
}

fun isElectrumServerDefault(): Boolean {
return useDefaultElectrum
}

fun getElectrumURL(): String {
return if (useDefaultElectrum) {
defaultElectrumURL
} else {
customElectrumURL
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright 2021-2023 thunderbiscuit and contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the ./LICENSE file.
*/

package com.goldenraven.devkitwallet.domain

import android.util.Log
import com.goldenraven.devkitwallet.utils.SharedPreferencesManager

private const val TAG = "Repository"

object Repository {

// shared preferences are a way to save/retrieve small pieces of data without building a database
private lateinit var sharedPreferencesManager: SharedPreferencesManager

fun setSharedPreferences(sharedPrefManager: SharedPreferencesManager) {
sharedPreferencesManager = sharedPrefManager
}

// take a look at shared preferences and see if the user already has a wallet saved on device
fun doesWalletExist(): Boolean {
val walletInitialized: Boolean = sharedPreferencesManager.walletInitialised
Log.i(TAG, "Value of walletInitialized at launch: $walletInitialized")
return walletInitialized
}

// save the necessary data for wallet reconstruction in shared preferences
// upon application launch, the wallet can initialize itself using that data
fun saveWallet(path: String, descriptor: String, changeDescriptor: String) {
Log.i(
TAG,
"Saved wallet:\npath -> $path \ndescriptor -> $descriptor \nchange descriptor -> $changeDescriptor"
)
sharedPreferencesManager.walletInitialised = true
sharedPreferencesManager.path = path
sharedPreferencesManager.descriptor = descriptor
sharedPreferencesManager.changeDescriptor = changeDescriptor
}

fun saveMnemonic(mnemonic: String) {
Log.i(TAG, "The recovery phrase is: $mnemonic")
sharedPreferencesManager.mnemonic = mnemonic
}

fun getMnemonic(): String {
return sharedPreferencesManager.mnemonic
}

fun getInitialWalletData(): RequiredInitialWalletData {
val descriptor: String = sharedPreferencesManager.descriptor
val changeDescriptor: String = sharedPreferencesManager.changeDescriptor
return RequiredInitialWalletData(descriptor, changeDescriptor)
}
}

data class RequiredInitialWalletData(
val descriptor: String,
val changeDescriptor: String
)
Loading
Loading