89 lines
3.3 KiB
Kotlin
89 lines
3.3 KiB
Kotlin
package com.bitcointxoko.gudariwallet.api
|
|
|
|
import com.bitcointxoko.gudariwallet.BuildConfig
|
|
import com.bitcointxoko.gudariwallet.security.SecretStore
|
|
import com.bitcointxoko.gudariwallet.util.WalletConstants
|
|
import kotlinx.coroutines.flow.first
|
|
import kotlinx.coroutines.runBlocking
|
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
|
import okhttp3.Interceptor
|
|
import okhttp3.OkHttpClient
|
|
import okhttp3.logging.HttpLoggingInterceptor
|
|
import retrofit2.Retrofit
|
|
import retrofit2.converter.gson.GsonConverterFactory
|
|
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)
|
|
.apply {
|
|
if (BuildConfig.DEBUG) {
|
|
addInterceptor(HttpLoggingInterceptor().apply {
|
|
level = HttpLoggingInterceptor.Level.BODY
|
|
})
|
|
}
|
|
}
|
|
.build()
|
|
|
|
fun create(secrets: SecretStore): LNbitsApi {
|
|
// Auth header interceptor — reads invoice key per-request (unchanged)
|
|
// val authInterceptor = Interceptor { chain ->
|
|
// val key = runBlocking { secrets.invoiceKey() }
|
|
// chain.proceed(
|
|
// chain.request().newBuilder()
|
|
// .header("X-Api-Key", key)
|
|
// .build()
|
|
// )
|
|
// }
|
|
|
|
// 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 realBaseUrl = runBlocking { secrets.baseUrl() }
|
|
.ifBlank { "https://placeholder.invalid" }
|
|
.trimEnd('/')
|
|
val realHttpUrl = realBaseUrl.toHttpUrl()
|
|
|
|
val originalUrl = chain.request().url
|
|
val newUrl = originalUrl.newBuilder()
|
|
.scheme(realHttpUrl.scheme)
|
|
.host(realHttpUrl.host)
|
|
.port(realHttpUrl.port)
|
|
.build()
|
|
|
|
chain.proceed(
|
|
chain.request().newBuilder()
|
|
.url(newUrl)
|
|
.build()
|
|
)
|
|
}
|
|
|
|
val client = httpClient.newBuilder()
|
|
// .addInterceptor(authInterceptor)
|
|
.addInterceptor(dynamicBaseUrlInterceptor)
|
|
.apply {
|
|
// Logging goes LAST — after URL rewrite — so logs show the real URL
|
|
if (BuildConfig.DEBUG) {
|
|
addInterceptor(HttpLoggingInterceptor().apply {
|
|
level = HttpLoggingInterceptor.Level.BODY
|
|
})
|
|
}
|
|
}
|
|
.build()
|
|
|
|
return Retrofit.Builder()
|
|
.baseUrl("https://placeholder.invalid/") // structurally required by Retrofit;
|
|
// always overwritten by the interceptor
|
|
.client(client)
|
|
.addConverterFactory(GsonConverterFactory.create(GsonProvider.gson))
|
|
.build()
|
|
.create(LNbitsApi::class.java)
|
|
}
|
|
}
|