Files
gudari/app/src/main/java/com/bitcointxoko/gudariwallet/api/LNbitsClient.kt
T

71 lines
2.7 KiB
Kotlin

package com.bitcointxoko.gudariwallet.api
import com.bitcointxoko.gudariwallet.security.SecretStore
import com.bitcointxoko.gudariwallet.util.WalletConstants
import kotlinx.coroutines.runBlocking
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.Interceptor
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.converter.kotlinx.serialization.asConverterFactory
import java.util.concurrent.TimeUnit
object LNbitsClient {
// Single shared client — used by both Retrofit and WebSocket
val httpClient: OkHttpClient = OkHttpClient.Builder()
.connectTimeout(WalletConstants.CONNECT_TIMEOUT_S, TimeUnit.SECONDS)
.readTimeout(WalletConstants.READ_TIMEOUT_S, TimeUnit.SECONDS)
.writeTimeout(WalletConstants.WRITE_TIMEOUT_S, TimeUnit.SECONDS)
.build()
fun create(secrets: SecretStore): LNbitsApi {
// Dynamic base URL interceptor — rewrites the placeholder host to the
// real base URL at request time, not at Retrofit construction time.
// This means credentials only need to be in DataStore by the time the
// first HTTP request fires, not at app startup.
val dynamicBaseUrlInterceptor = Interceptor { chain ->
val originalRequest = chain.request()
val originalUrl = originalRequest.url
// Only rewrite requests targeting the Retrofit placeholder host.
// External LNURL/Lightning Address requests must pass through unchanged.
if (originalUrl.host != "placeholder.invalid") {
return@Interceptor chain.proceed(originalRequest)
}
val realBaseUrl = runBlocking { secrets.baseUrl() }
.ifBlank { "https://placeholder.invalid" }
.trimEnd('/')
val realHttpUrl = realBaseUrl.toHttpUrl()
val newUrl = originalUrl.newBuilder()
.scheme(realHttpUrl.scheme)
.host(realHttpUrl.host)
.port(realHttpUrl.port)
.build()
chain.proceed(
originalRequest.newBuilder()
.url(newUrl)
.build()
)
}
val client = httpClient.newBuilder()
.addInterceptor(dynamicBaseUrlInterceptor)
.build()
return Retrofit.Builder()
.baseUrl("https://placeholder.invalid/") // structurally required by Retrofit;
.client(client)
.addConverterFactory(
JsonProvider.json.asConverterFactory(
"application/json; charset=UTF-8".toMediaType()
)
) .build()
.create(LNbitsApi::class.java)
}
}