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
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ class DeviceAssetsSyncService @Inject constructor(
) {

suspend fun sync(walletId: String) {
val walletIdentifier = WalletId(walletId)
val preferences = walletPreferencesFactory.create(walletId)
val assetIds = gemDeviceApiClient.getAssets(
walletId = walletId,
walletId = walletIdentifier,
fromTimestamp = preferences.assetsTimestamp,
).mapNotNull(String::toAssetId)
.distinct()
Expand All @@ -40,7 +41,7 @@ class DeviceAssetsSyncService @Inject constructor(
return
}

val wallet = walletsRepository.getWallet(WalletId(walletId)).firstOrNull() ?: return
val wallet = walletsRepository.getWallet(walletIdentifier).firstOrNull() ?: return
val existingAssetIds = assetsRepository.hasWalletAssets(wallet.id.id, assetIds)
val missingAssetIds = assetIds.filterNot(existingAssetIds::contains)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import com.gemwallet.android.data.repositories.assets.AssetsRepository
import com.gemwallet.android.data.repositories.session.SessionRepository
import com.gemwallet.android.data.service.store.WalletPreferencesFactory
import com.gemwallet.android.data.services.gemapi.GemDeviceApiClient
import com.wallet.core.primitives.WalletId
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
Expand All @@ -30,7 +31,7 @@ object WalletImportModule {
fun provideGetAvailableAssetIds(
gemDeviceApiClient: GemDeviceApiClient,
): GetAvailableAssetIds = GetAvailableAssetIds { walletId ->
gemDeviceApiClient.getAssets(walletId = walletId, fromTimestamp = 0)
gemDeviceApiClient.getAssets(walletId = WalletId(walletId), fromTimestamp = 0)
}

@Provides
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class GetBuyQuoteUrlImpl(
override suspend fun invoke(quoteId: String, walletId: WalletId): String? {
return try {
gemDeviceApiClient.getFiatQuoteUrl(
walletId = walletId.id,
walletId = walletId,
quoteId = quoteId,
)?.redirectUrl
} catch (_: Exception) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class GetBuyQuotesImpl(
assetId = asset.id.toIdentifier(),
amount = amount,
currency = fiatCurrency,
walletId = walletId.id,
walletId = walletId,
type = type.string,
)?.quotes ?: throw IOException()
} catch (err: Exception) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ class GetFiatTransactionsImpl(
private val gemDeviceApiClient: GemDeviceApiClient,
) : GetFiatTransactions {
override suspend fun invoke(walletId: WalletId): List<FiatTransactionData> {
return gemDeviceApiClient.getFiatTransactions(walletId.id)
return gemDeviceApiClient.getFiatTransactions(walletId)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class CreateReferralImpl(
val account = wallet.getAccount(Chain.referralChain) ?: throw ReferralError.BadWallet
val authPayload = getAuthPayload.getAuthPayload(wallet, account.chain)
return gemDeviceApiClient.createReferral(
walletId = wallet.id.id,
walletId = wallet.id,
body = AuthenticatedRequest(
auth = authPayload,
data = ReferralCode(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class GetRewardsImpl(
private val gemDeviceApiClient: GemDeviceApiClient,
) : GetRewards {
override suspend fun getRewards(walletId: WalletId): Rewards {
val response = gemDeviceApiClient.getRewards(walletId.id)
val response = gemDeviceApiClient.getRewards(walletId)
if (response?.code == null) {
throw ReferralError.NotCreated
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class RedeemImpl(
throw ReferralError.InsufficientPoints
}
val result = gemDeviceApiClient.redeem(
walletId = wallet.id.id,
walletId = wallet.id,
request = AuthenticatedRequest(
auth = authPayload,
data = RedemptionRequest(option.id)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class UseReferralCodeImpl(
val account = wallet.getAccount(Chain.referralChain) ?: throw ReferralError.BadWallet
val auth = getAuthPayload.getAuthPayload(wallet, account.chain)
gemDeviceApiClient.useReferralCode(
walletId = wallet.id.id,
walletId = wallet.id,
body = AuthenticatedRequest(
auth = auth,
data = ReferralCode(code)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ class SyncTransactionsImpl @Inject constructor(
) : SyncTransactions, SyncAssetTransactions {

override suspend fun syncTransactions(wallet: Wallet) {
val walletId = wallet.id.id
val preferences = walletPreferencesFactory.create(walletId)
val walletId = wallet.id
val preferences = walletPreferencesFactory.create(walletId.id)
val response = runCatching {
gemDeviceApiClient.getTransactions(walletId, preferences.transactionsTimestamp)
}.getOrNull() ?: return
Expand All @@ -46,8 +46,8 @@ class SyncTransactionsImpl @Inject constructor(
}

private suspend fun syncAssetTransactions(wallet: Wallet, assetId: AssetId) {
val walletId = wallet.id.id
val preferences = walletPreferencesFactory.create(walletId)
val walletId = wallet.id
val preferences = walletPreferencesFactory.create(walletId.id)
val assetIdentifier = assetId.identifier
val timestamp = preferences.transactionsForAssetTimestamp(assetIdentifier)
val response = runCatching {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class SyncWalletConfigurationImpl(
val preferences = walletPreferencesFactory.create(walletId.id)
if (preferences.completeInitialWalletConfiguration) return

val configuration = runCatching { gemDeviceApiClient.getWalletConfiguration(walletId.id).configuration }
val configuration = runCatching { gemDeviceApiClient.getWalletConfiguration(walletId).configuration }
.getOrNull() ?: return

configuration.multiSignatureAccounts.forEach { account ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class SyncWalletConfigurationImplTest {

@Test
fun sync_addsMultisigBannerForEachReturnedAccountAndMarksComplete() = runTest {
coEvery { gemDeviceApiClient.getWalletConfiguration("wallet-1") } returns WalletConfigurationResult(
coEvery { gemDeviceApiClient.getWalletConfiguration(walletId) } returns WalletConfigurationResult(
walletId = walletId,
configuration = WalletConfiguration(
multiSignatureAccounts = listOf(
Expand Down Expand Up @@ -71,7 +71,7 @@ class SyncWalletConfigurationImplTest {

@Test
fun sync_doesNothingWhenMultiSignatureAccountsIsEmpty() = runTest {
coEvery { gemDeviceApiClient.getWalletConfiguration("wallet-1") } returns WalletConfigurationResult(
coEvery { gemDeviceApiClient.getWalletConfiguration(walletId) } returns WalletConfigurationResult(
walletId = walletId,
configuration = WalletConfiguration(multiSignatureAccounts = emptyList()),
)
Expand All @@ -84,7 +84,7 @@ class SyncWalletConfigurationImplTest {

@Test
fun sync_swallowsApiFailuresAndDoesNotMarkComplete() = runTest {
coEvery { gemDeviceApiClient.getWalletConfiguration("wallet-1") } throws RuntimeException("network down")
coEvery { gemDeviceApiClient.getWalletConfiguration(walletId) } throws RuntimeException("network down")

subject.sync(walletId)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class NftRepository(

@Throws(HttpException::class, IOException::class)
override suspend fun sync(walletId: WalletId) {
val nftData = gemDeviceApiClient.getNFTs(walletId = walletId.id).orEmpty()
val nftData = gemDeviceApiClient.getNFTs(walletId = walletId).orEmpty()
val collections = nftData.map { it.collection.toDb() }
val assets = nftData.flatMap { it.assets }.map { it.toDb() }
val associations = assets.map { DbNFTAssociation(walletId = walletId.id, assetId = it.id) }
Expand All @@ -44,7 +44,7 @@ class NftRepository(

@Throws(HttpException::class, IOException::class)
override suspend fun refreshNftAsset(wallet: Wallet, assetId: NFTAssetId) {
gemDeviceApiClient.refreshNftAsset(wallet.id.id, assetId.toIdentifier())
gemDeviceApiClient.refreshNftAsset(wallet.id, assetId.toIdentifier())
}

override fun getListNft(walletId: WalletId, collectionId: String?): Flow<List<NFTData>> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,18 @@ import com.wallet.core.primitives.Rewards
import com.wallet.core.primitives.ScanTransaction
import com.wallet.core.primitives.ScanTransactionPayload
import com.wallet.core.primitives.Transaction
import com.wallet.core.primitives.WalletId
import com.wallet.core.primitives.WalletSubscription
import com.wallet.core.primitives.WalletSubscriptionChains
import com.wallet.core.primitives.WalletConfigurationResult
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.HTTP
import retrofit2.http.Header
import retrofit2.http.POST
import retrofit2.http.PUT
import retrofit2.http.Path
import retrofit2.http.Query

const val WALLET_ID_HEADER = "x-wallet-id"
import retrofit2.http.Tag

interface GemDeviceApiClient {

Expand Down Expand Up @@ -76,33 +75,33 @@ interface GemDeviceApiClient {

// Rewards
@GET("/v2/devices/rewards")
suspend fun getRewards(@Header(WALLET_ID_HEADER) walletId: String): Rewards?
suspend fun getRewards(@Tag walletId: WalletId): Rewards?

@GET("/v2/devices/rewards/events")
suspend fun getRewardsEvents(@Header(WALLET_ID_HEADER) walletId: String): List<RewardEvent>
suspend fun getRewardsEvents(@Tag walletId: WalletId): List<RewardEvent>

@GET("/v2/devices/rewards/redemptions/{code}")
suspend fun getRedemptionOption(@Path("code") code: String): RewardRedemptionOption

@POST("/v2/devices/rewards/referrals/create")
suspend fun createReferral(@Header(WALLET_ID_HEADER) walletId: String, @Body body: AuthenticatedRequest<ReferralCode>): Rewards?
suspend fun createReferral(@Tag walletId: WalletId, @Body body: AuthenticatedRequest<ReferralCode>): Rewards?

@POST("/v2/devices/rewards/referrals/use")
suspend fun useReferralCode(@Header(WALLET_ID_HEADER) walletId: String, @Body body: AuthenticatedRequest<ReferralCode>): Boolean
suspend fun useReferralCode(@Tag walletId: WalletId, @Body body: AuthenticatedRequest<ReferralCode>): Boolean

@POST("/v2/devices/rewards/redeem")
suspend fun redeem(@Header(WALLET_ID_HEADER) walletId: String, @Body request: AuthenticatedRequest<RedemptionRequest>): RedemptionResult
suspend fun redeem(@Tag walletId: WalletId, @Body request: AuthenticatedRequest<RedemptionRequest>): RedemptionResult

// Transactions
@GET("/v2/devices/transactions")
suspend fun getTransactions(
@Header(WALLET_ID_HEADER) walletId: String,
@Tag walletId: WalletId,
@Query("from_timestamp") from: Long,
): TransactionsResponse?

@GET("/v2/devices/transactions")
suspend fun getTransactions(
@Header(WALLET_ID_HEADER) walletId: String,
@Tag walletId: WalletId,
@Query("asset_id") assetId: String,
@Query("from_timestamp") from: Long,
): TransactionsResponse?
Expand All @@ -114,21 +113,21 @@ interface GemDeviceApiClient {
suspend fun getScanTransaction(@Body payload: ScanTransactionPayload): ScanTransaction

@GET("/v2/devices/wallet_configuration")
suspend fun getWalletConfiguration(@Header(WALLET_ID_HEADER) walletId: String): WalletConfigurationResult
suspend fun getWalletConfiguration(@Tag walletId: WalletId): WalletConfigurationResult

// Assets
@GET("/v2/devices/assets")
suspend fun getAssets(@Header(WALLET_ID_HEADER) walletId: String, @Query("from_timestamp") fromTimestamp: Long): List<String>
suspend fun getAssets(@Tag walletId: WalletId, @Query("from_timestamp") fromTimestamp: Long): List<String>

// NFT
@GET("/v2/devices/nft_assets")
suspend fun getNFTs(@Header(WALLET_ID_HEADER) walletId: String): List<NFTData>?
suspend fun getNFTs(@Tag walletId: WalletId): List<NFTData>?

@GET("/v2/devices/nft_assets/{asset_id}")
suspend fun getNFT(@Path("asset_id") assetId: String): NFTAssetData

@POST("/v2/devices/nft_assets/{asset_id}/refresh")
suspend fun refreshNftAsset(@Header(WALLET_ID_HEADER) walletId: String, @Path("asset_id") assetId: String): Boolean
suspend fun refreshNftAsset(@Tag walletId: WalletId, @Path("asset_id") assetId: String): Boolean

// AUTH
@GET("/v2/devices/auth/nonce")
Expand All @@ -143,7 +142,7 @@ interface GemDeviceApiClient {

@GET("/v2/devices/fiat/quotes/{type}/{asset_id}")
suspend fun getFiatQuotes(
@Header(WALLET_ID_HEADER) walletId: String,
@Tag walletId: WalletId,
@Path("type") type: String,
@Path("asset_id") assetId: String,
@Query("amount") amount: Double,
Expand All @@ -152,13 +151,13 @@ interface GemDeviceApiClient {

@GET("/v2/devices/fiat/quotes/{quote_id}/url")
suspend fun getFiatQuoteUrl(
@Header(WALLET_ID_HEADER) walletId: String,
@Tag walletId: WalletId,
@Path("quote_id") quoteId: String
): FiatQuoteUrl?

@GET("/v2/devices/fiat/transactions")
suspend fun getFiatTransactions(
@Header(WALLET_ID_HEADER) walletId: String,
@Tag walletId: WalletId,
): List<FiatTransactionData>

}
Original file line number Diff line number Diff line change
@@ -1,25 +1,31 @@
package com.gemwallet.android.data.services.gemapi.http

import com.gemwallet.android.application.device.coordinators.GetDeviceId
import com.wallet.core.primitives.WalletId
import okhttp3.Interceptor
import okhttp3.Protocol
import okhttp3.Response
import okio.Buffer

class SecurityInterceptor(
private val getDeviceId: GetDeviceId,
class SecurityInterceptor internal constructor(
private val signer: DeviceRequestSigner,
) : Interceptor {

private val signer = DeviceRequestSigner(getDeviceId)
constructor(getDeviceId: GetDeviceId) : this(DeviceRequestSigner(getDeviceId))

override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
val body = request.body?.let {
val buffer = Buffer()
it.writeTo(buffer)
buffer.readUtf8().toByteArray()
buffer.readByteArray()
}
val signature = signer.sign(request.method, request.url.encodedPath, body)
val signature = signer.sign(
method = request.method,
path = request.url.encodedPath,
body = body,
walletId = request.tag(WalletId::class.java)?.id.orEmpty(),
)
return try {
val builder = request.newBuilder()
signature.toHeaders().forEach { (key, value) -> builder.header(key, value) }
Expand Down
Loading