Updated on 2026-08-14
This commit is contained in:
parent
d8f9a85560
commit
1c82ef2c7b
12 changed files with 332 additions and 57 deletions
|
|
@ -0,0 +1,40 @@
|
|||
package com.tangem.server_android
|
||||
|
||||
import kotlinx.coroutines.delay
|
||||
import java.io.IOException
|
||||
|
||||
|
||||
suspend fun <T> retryIO(
|
||||
times: Int = 3,
|
||||
initialDelay: Long = 100,
|
||||
maxDelay: Long = 1000,
|
||||
factor: Double = 2.0,
|
||||
block: suspend () -> T): T
|
||||
{
|
||||
var currentDelay = initialDelay
|
||||
repeat(times - 1) {
|
||||
try {
|
||||
return block()
|
||||
} catch (e: IOException) {
|
||||
// you can log an error here and/or make a more finer-grained
|
||||
// analysis of the cause to see if retry is needed
|
||||
}
|
||||
delay(currentDelay)
|
||||
currentDelay = (currentDelay * factor).toLong().coerceAtMost(maxDelay)
|
||||
}
|
||||
return block()
|
||||
}
|
||||
|
||||
sealed class Result<out T> {
|
||||
data class Success<out T>(val data: T) : Result<T>()
|
||||
data class Failure(val error: Throwable?) : Result<Nothing>()
|
||||
}
|
||||
|
||||
suspend fun <T>performRequest(block: suspend () -> T): Result<T> {
|
||||
return try {
|
||||
val result = retryIO { block() }
|
||||
Result.Success(result)
|
||||
} catch (exception: Exception) {
|
||||
Result.Failure(exception)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
package com.tangem.server_android
|
||||
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.logging.HttpLoggingInterceptor
|
||||
import retrofit2.Retrofit
|
||||
import retrofit2.converter.gson.GsonConverterFactory
|
||||
|
||||
class PayIdService {
|
||||
|
||||
private val tangemApi: TangemApi by lazy {
|
||||
provideRetrofit()
|
||||
.create(TangemApi::class.java)
|
||||
}
|
||||
|
||||
suspend fun getPayId(cardId: String, publicKey: String): Result<PayIdResponse> {
|
||||
return performRequest { tangemApi.getPayId(cardId, publicKey) }
|
||||
}
|
||||
|
||||
suspend fun setPayId(cardId: String, publicKey: String, payId: String, address: String, network: String): Result<SetPayIdResponse> {
|
||||
return performRequest { tangemApi.setPayId(cardId, publicKey, payId, address, network) }
|
||||
}
|
||||
}
|
||||
|
||||
data class PayIdResponse(
|
||||
val payId: String
|
||||
)
|
||||
|
||||
data class SetPayIdResponse(
|
||||
val success: Boolean
|
||||
)
|
||||
|
||||
fun provideRetrofit(): Retrofit {
|
||||
val builder = Retrofit.Builder()
|
||||
.baseUrl("https://tangem.com/")
|
||||
.addConverterFactory(GsonConverterFactory.create())
|
||||
if (BuildConfig.DEBUG)
|
||||
builder.client(createOkHttpClient())
|
||||
return builder.build()
|
||||
}
|
||||
|
||||
private fun createOkHttpClient(): OkHttpClient {
|
||||
return OkHttpClient.Builder().addInterceptor(createHttpLoggingInterceptor()).build()
|
||||
}
|
||||
|
||||
private fun createHttpLoggingInterceptor(): HttpLoggingInterceptor {
|
||||
val logging = HttpLoggingInterceptor()
|
||||
logging.level = HttpLoggingInterceptor.Level.BODY
|
||||
return logging
|
||||
}
|
||||
|
|
@ -12,6 +12,7 @@ public class Server {
|
|||
static final String VERIFY = URL_TANGEM + "verify";
|
||||
static final String VERIFY_AND_GET_INFO = URL_TANGEM + "card/verify-and-get-info";
|
||||
static final String ARTWORK = URL_TANGEM + "card/artwork";
|
||||
static final String PAY_ID = ServerURL.API_PAY_ID_TANGEM;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,4 +2,5 @@ package com.tangem.server_android;
|
|||
|
||||
class ServerURL {
|
||||
static final String API_TANGEM = "https://verify.tangem.com/";
|
||||
static final String API_PAY_ID_TANGEM = "https://payid.tangem.com/";
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
package com.tangem.server_android;
|
||||
|
||||
import com.tangem.server_android.model.CardVerifyAndGetInfo;
|
||||
|
||||
import okhttp3.ResponseBody;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.http.Body;
|
||||
import retrofit2.http.GET;
|
||||
import retrofit2.http.Headers;
|
||||
import retrofit2.http.POST;
|
||||
import retrofit2.http.Query;
|
||||
|
||||
public interface TangemApi {
|
||||
@Headers("Content-Type: application/json")
|
||||
@POST(Server.ApiTangem.Method.VERIFY_AND_GET_INFO)
|
||||
Call<CardVerifyAndGetInfo.Response> getCardVerifyAndGetInfo(@Body CardVerifyAndGetInfo.Request requestBody);
|
||||
|
||||
@GET(Server.ApiTangem.Method.ARTWORK)
|
||||
Call<ResponseBody> getArtwork(@Query("artworkId") String artworkId, @Query("CID") String CID, @Query("publicKey") String publicKey);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
package com.tangem.server_android
|
||||
|
||||
import com.tangem.server_android.model.CardVerifyAndGetInfo
|
||||
import okhttp3.ResponseBody
|
||||
import retrofit2.Call
|
||||
import retrofit2.http.*
|
||||
|
||||
interface TangemApi {
|
||||
@Headers("Content-Type: application/json")
|
||||
@POST(Server.ApiTangem.Method.VERIFY_AND_GET_INFO)
|
||||
fun getCardVerifyAndGetInfo(@Body requestBody: CardVerifyAndGetInfo.Request?): Call<CardVerifyAndGetInfo.Response>
|
||||
|
||||
@GET(Server.ApiTangem.Method.ARTWORK)
|
||||
fun getArtwork(
|
||||
@Query("artworkId") artworkId: String?,
|
||||
@Query("CID") CID: String?,
|
||||
@Query("publicKey") publicKey: String?
|
||||
): Call<ResponseBody>
|
||||
|
||||
@GET(Server.ApiTangem.Method.PAY_ID)
|
||||
suspend fun getPayId(
|
||||
@Query("cid") cardId: String,
|
||||
@Query("key") publicKey: String
|
||||
): PayIdResponse
|
||||
|
||||
@POST(Server.ApiTangem.Method.PAY_ID)
|
||||
suspend fun setPayId(
|
||||
@Query("cid") cardId: String,
|
||||
@Query("key") publicKey: String,
|
||||
@Query("payid") payId: String,
|
||||
@Query("address") address: String,
|
||||
@Query("network") network: String
|
||||
): SetPayIdResponse
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue