@@ -7,103 +7,36 @@ import io.ktor.client.request.post
77import io.ktor.client.request.setBody
88import io.ktor.client.statement.HttpResponse
99import io.ktor.http.isSuccess
10- import kotlinx.serialization.Serializable
11- import kotlinx.serialization.json.JsonObject
1210import to.bitkit.env.Env
1311import to.bitkit.models.FxRateResponse
14- import to.bitkit.models.blocktank.RegtestCloseChannelRequest
15- import to.bitkit.models.blocktank.RegtestDepositRequest
16- import to.bitkit.models.blocktank.RegtestMineRequest
17- import to.bitkit.models.blocktank.RegtestPayRequest
1812import to.bitkit.utils.AppError
1913import to.bitkit.utils.Logger
2014import javax.inject.Inject
2115import javax.inject.Singleton
2216
23- private typealias IgnoreResponse = String
24-
2517@Singleton
2618class BlocktankHttpClient @Inject constructor(
2719 private val client : HttpClient ,
2820) {
29- // region notifications
30- suspend fun registerDevice (payload : RegisterDeviceRequest ) {
31- post<IgnoreResponse >(" ${Env .blocktankPushNotificationServer} /device" , payload)
32- }
33-
34- suspend fun testNotification (deviceToken : String , payload : TestNotificationRequest ) {
35- post<IgnoreResponse >(" ${Env .blocktankPushNotificationServer} /device/$deviceToken /test-notification" , payload)
36- }
37- // endregion
38-
3921 // region rates
4022 suspend fun fetchLatestRates (): FxRateResponse {
4123 return get<FxRateResponse >(Env .btcRatesServer)
4224 }
4325 // endregion
4426
45- // region regtest
46- /* *
47- * Mines a number of blocks on the regtest network.
48- * @param count Number of blocks to mine. Default is 1.
49- */
50- suspend fun regtestMine (count : Int = 1) {
51- val payload = RegtestMineRequest (count)
52- post<IgnoreResponse >(" ${Env .blocktankClientServer} /regtest/chain/mine" , payload)
53- }
54-
55- /* *
56- * Deposits a number of satoshis to an address on the regtest network.
57- * @param address Address to deposit to.
58- * @param amountSat Amount of satoshis to deposit. Default is 10,000,000.
59- * @return Onchain transaction ID.
60- */
61- suspend fun regtestDeposit (address : String , amountSat : Int = 10_000_000): String {
62- val payload = RegtestDepositRequest (address = address, amountSat = amountSat)
63- return post(" ${Env .blocktankClientServer} /regtest/chain/deposit" , payload)
64- }
65-
66- /* *
67- * Pays an invoice on the regtest network.
68- * @param invoice Invoice to pay.
69- * @param amountSat Amount of satoshis to pay (only for 0-amount invoices).
70- * @return Blocktank payment ID.
71- */
72- suspend fun regtestPay (invoice : String , amountSat : Int? = null): String {
73- val payload = RegtestPayRequest (invoice = invoice, amountSat = amountSat)
74- return post(" ${Env .blocktankClientServer} /regtest/channel/pay" , payload)
75- }
76-
77- /* *
78- * Closes a channel on the regtest network.
79- * @param fundingTxId Funding transaction ID.
80- * @param vout Funding transaction output index.
81- * @param forceCloseAfterS Time in seconds to force-close the channel after. Default is 24 hours (86400). Set it to 0 for immediate force close.
82- * @return Closing transaction ID.
83- */
84- suspend fun regtestCloseChannel (fundingTxId : String , vout : Int , forceCloseAfterS : Int = 86400): String {
85- val payload = RegtestCloseChannelRequest (
86- fundingTxId = fundingTxId,
87- vout = vout,
88- forceCloseAfterS = forceCloseAfterS,
89- )
90- return post(" ${Env .blocktankClientServer} /regtest/channel/close" , payload)
91- }
92- // endregion
93-
9427 // region utils
9528 private suspend inline fun <reified T > post (url : String , payload : Any? = null): T {
9629 val response = client.post(url) { payload?.let { setBody(it) } }
9730 Logger .debug(" Http call: $response " )
9831 return when (response.status.isSuccess()) {
9932 true -> {
10033 val responseBody = runCatching { response.body<T >() }.getOrElse {
101- throw BlocktankErrorOld .InvalidResponse (it.message.orEmpty())
34+ throw BlocktankHttpError .InvalidResponse (it.message.orEmpty())
10235 }
10336 responseBody
10437 }
10538
106- else -> throw BlocktankErrorOld .InvalidResponse (response.status.description)
39+ else -> throw BlocktankHttpError .InvalidResponse (response.status.description)
10740 }
10841 }
10942
@@ -117,39 +50,17 @@ class BlocktankHttpClient @Inject constructor(
11750 return when (response.status.isSuccess()) {
11851 true -> {
11952 val responseBody = runCatching { response.body<T >() }.getOrElse {
120- throw BlocktankErrorOld .InvalidResponse (it.message.orEmpty())
53+ throw BlocktankHttpError .InvalidResponse (it.message.orEmpty())
12154 }
12255 responseBody
12356 }
12457
125- else -> throw BlocktankErrorOld .InvalidResponse (response.status.description)
58+ else -> throw BlocktankHttpError .InvalidResponse (response.status.description)
12659 }
12760 }
12861 // endregion
12962}
13063
131- sealed class BlocktankErrorOld (message : String ) : AppError(message) {
132- data class InvalidResponse (override val message : String ) : BlocktankErrorOld(message)
133- }
134-
135- @Serializable
136- data class RegisterDeviceRequest (
137- val deviceToken : String ,
138- val publicKey : String ,
139- val features : List <String >,
140- val nodeId : String ,
141- val isoTimestamp : String ,
142- val signature : String ,
143- )
144-
145- @Serializable
146- data class TestNotificationRequest (
147- val data : Data ,
148- ) {
149- @Serializable
150- data class Data (
151- val source : String ,
152- val type : String ,
153- val payload : JsonObject ,
154- )
64+ sealed class BlocktankHttpError (message : String ) : AppError(message) {
65+ data class InvalidResponse (override val message : String ) : BlocktankHttpError(message)
15566}
0 commit comments