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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,16 @@
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="@string/app_notifications_channel_id" />

<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
</application>

</manifest>
24 changes: 14 additions & 10 deletions app/src/main/java/to/bitkit/env/Env.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import to.bitkit.ext.ensureDir
import to.bitkit.models.LnPeer
import to.bitkit.models.blocktank.BlocktankNotificationType
import to.bitkit.utils.Logger
import java.io.File
import kotlin.io.path.Path

@Suppress("ConstPropertyName")
Expand All @@ -17,6 +18,8 @@ internal object Env {
val defaultWalletWordCount = 12
val walletSyncIntervalSecs = 10_uL // TODO review
val ldkNodeSyncIntervalSecs = 60_uL // TODO review

// TODO: remove this to load from BT API instead
val trustedLnPeers
get() = when (network) {
Network.REGTEST -> listOf(
Expand Down Expand Up @@ -83,25 +86,25 @@ internal object Env {
appStoragePath = path
}

fun ldkLogFilePath(walletIndex: Int): String {
val logPath = Path(ldkStoragePath(walletIndex), "ldk_node_latest.log").toFile().absolutePath
Logger.info("LDK-node log path: $logPath")
return logPath
}
val logDir: String
get() {
require(::appStoragePath.isInitialized)
return File(appStoragePath).resolve("logs").ensureDir().path
}

val ldkLogLevel = LogLevel.TRACE

fun ldkStoragePath(walletIndex: Int) = storagePathOf(walletIndex, network.name.lowercase(), "ldk")
fun bitkitCoreStoragePath(walletIndex: Int) = storagePathOf(walletIndex, network.name.lowercase(), "core")

private fun storagePathOf(walletIndex: Int, network: String, dir: String): String {
require(::appStoragePath.isInitialized) { "App storage path should be init as context.filesDir.absolutePath." }
val absolutePath = Path(appStoragePath, network, "wallet$walletIndex", dir)
require(::appStoragePath.isInitialized) { "App storage path should be 'context.filesDir.absolutePath'." }
val path = Path(appStoragePath, network, "wallet$walletIndex", dir)
.toFile()
.ensureDir()
.absolutePath
Logger.debug("Using ${dir.uppercase()} storage path: $absolutePath")
return absolutePath
.path
Logger.debug("Using ${dir.uppercase()} storage path: $path")
return path
}

object Peers {
Expand All @@ -114,4 +117,5 @@ internal object Env {
const val PIN_LENGTH = 4
const val PIN_ATTEMPTS = 8
const val DEFAULT_INVOICE_MESSAGE = "Bitkit"
const val FILE_PROVIDER_AUTHORITY = "${BuildConfig.APPLICATION_ID}.fileprovider"
}
1 change: 1 addition & 0 deletions app/src/main/java/to/bitkit/ext/DateTime.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ object DatePattern {
const val DATE_TIME = "dd/MM/yyyy, HH:mm"
const val INVOICE_EXPIRY = "MMM dd, h:mm a"
const val ACTIVITY_ITEM = "MMMM d yyyy, HH:mm"
const val LOG_FILE = "yyyy-MM-dd_HH-mm-ss"
}
23 changes: 21 additions & 2 deletions app/src/main/java/to/bitkit/services/LightningService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import to.bitkit.async.ServiceQueue
import to.bitkit.data.keychain.Keychain
import to.bitkit.di.BgDispatcher
import to.bitkit.env.Env
import to.bitkit.ext.DatePattern
import to.bitkit.ext.millis
import to.bitkit.ext.toHex
import to.bitkit.ext.toSha256
Expand All @@ -44,6 +45,11 @@ import to.bitkit.models.LnPeer.Companion.toLnPeer
import to.bitkit.utils.LdkError
import to.bitkit.utils.Logger
import to.bitkit.utils.ServiceError
import java.io.File
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import java.util.TimeZone
import javax.inject.Inject
import javax.inject.Singleton
import kotlin.io.path.Path
Expand Down Expand Up @@ -79,7 +85,8 @@ class LightningService @Inject constructor(
)
})
.apply {
setFilesystemLogger(Env.ldkLogFilePath(walletIndex), Env.ldkLogLevel)
setFilesystemLogger(generateLogFilePath(), Env.ldkLogLevel)

setChainSourceEsplora(
serverUrl = Env.esploraServerUrl,
config = EsploraSyncConfig(
Expand Down Expand Up @@ -354,7 +361,7 @@ class LightningService @Inject constructor(
return true
}

//TODO: get feeRate from real source
// TODO: get feeRate from real source
suspend fun send(address: Address, sats: ULong, satKwu: ULong = 250uL * 5uL): Txid {
val node = this.node ?: throw ServiceError.NodeNotSetup

Expand Down Expand Up @@ -480,6 +487,18 @@ class LightningService @Inject constructor(
}
}.flowOn(bgDispatcher)
// endregion

private fun generateLogFilePath(): String {
val dateFormatter = SimpleDateFormat(DatePattern.LOG_FILE, Locale.US).apply {
timeZone = TimeZone.getTimeZone("UTC")
}
val timestamp = dateFormatter.format(Date())

val sessionLogFilePath = File(Env.logDir).resolve("ldk_$timestamp.log").path

Logger.debug("Generated LDK log file path: $sessionLogFilePath")
return sessionLogFilePath
}
}

// region helpers
Expand Down
36 changes: 34 additions & 2 deletions app/src/main/java/to/bitkit/ui/ContentView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -76,16 +76,18 @@ import to.bitkit.ui.settings.DefaultUnitSettingsScreen
import to.bitkit.ui.settings.GeneralSettingsScreen
import to.bitkit.ui.settings.LightningSettingsScreen
import to.bitkit.ui.settings.LocalCurrencySettingsScreen
import to.bitkit.ui.settings.LogDetailScreen
import to.bitkit.ui.settings.LogsScreen
import to.bitkit.ui.settings.OrderDetailScreen
import to.bitkit.ui.settings.SecuritySettingsScreen
import to.bitkit.ui.settings.SettingsScreen
import to.bitkit.ui.settings.backups.BackupWalletScreen
import to.bitkit.ui.settings.backups.RestoreWalletScreen
import to.bitkit.ui.settings.pin.ChangePinConfirmScreen
import to.bitkit.ui.settings.pin.ChangePinScreen
import to.bitkit.ui.settings.pin.DisablePinScreen
import to.bitkit.ui.settings.pin.ChangePinNewScreen
import to.bitkit.ui.settings.pin.ChangePinResultScreen
import to.bitkit.ui.settings.pin.ChangePinScreen
import to.bitkit.ui.settings.pin.DisablePinScreen
import to.bitkit.ui.utils.screenScaleIn
import to.bitkit.ui.utils.screenScaleOut
import to.bitkit.ui.utils.screenSlideIn
Expand Down Expand Up @@ -262,6 +264,7 @@ fun ContentView(
activityItem(activityListViewModel, navController)
qrScanner(appViewModel, navController)
authCheck(navController)
logs(navController)

// TODO extract transferNavigation
navigation<Routes.TransferRoot>(
Expand Down Expand Up @@ -692,6 +695,21 @@ private fun NavGraphBuilder.authCheck(
)
}
}

private fun NavGraphBuilder.logs(
navController: NavHostController,
) {
composableWithDefaultTransitions<Routes.Logs> {
LogsScreen(navController)
}
composableWithDefaultTransitions<Routes.LogDetail> { navBackEntry ->
val route = navBackEntry.toRoute<Routes.LogDetail>()
LogDetailScreen(
navController = navController,
fileName = route.fileName,
)
}
}
// endregion

/**
Expand Down Expand Up @@ -850,6 +868,14 @@ fun NavController.navigateToActivityItem(id: String) = navigate(
fun NavController.navigateToQrScanner() = navigate(
route = Routes.QrScanner,
)

fun NavController.navigateToLogs() = navigate(
route = Routes.Logs,
)

fun NavController.navigateToLogDetail(fileName: String) = navigate(
route = Routes.LogDetail(fileName),
)
// endregion

object Routes {
Expand Down Expand Up @@ -909,6 +935,12 @@ object Routes {
@Serializable
data object ChannelOrdersSettings

@Serializable
data object Logs

@Serializable
data class LogDetail(val fileName: String)

@Serializable
data class OrderDetail(val id: String)

Expand Down
Loading