Skip to content

Commit

Permalink
MRKT-141 | Added newm token cost to GetMarketplaceSale response
Browse files Browse the repository at this point in the history
  • Loading branch information
wlara committed Aug 30, 2024
1 parent 6a2493c commit aba6a6f
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ interface CardanoRepository {
assetName: String
): Long

suspend fun isNewmToken(
policyId: String,
assetName: String
): Boolean

suspend fun <T> withLock(block: suspend () -> T): T

suspend fun verifySignData(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,6 @@ import io.newm.txbuilder.ktx.fingerprint
import io.newm.txbuilder.ktx.mergeAmounts
import io.newm.txbuilder.ktx.toCborObject
import io.newm.txbuilder.ktx.toNativeAssetMap
import java.time.Duration
import java.util.UUID
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlin.coroutines.suspendCoroutine
import kotlin.time.Duration.Companion.minutes
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
Expand All @@ -105,6 +99,12 @@ import software.amazon.awssdk.core.SdkBytes
import software.amazon.awssdk.services.kms.KmsAsyncClient
import software.amazon.awssdk.services.kms.model.DecryptRequest
import software.amazon.awssdk.services.kms.model.EncryptRequest
import java.time.Duration
import java.util.UUID
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlin.coroutines.suspendCoroutine
import kotlin.time.Duration.Companion.minutes

internal class CardanoRepositoryImpl(
private val client: NewmChainCoroutineStub,
Expand Down Expand Up @@ -425,14 +425,22 @@ internal class CardanoRepositoryImpl(
policyId: String,
assetName: String
): Long {
if ((isMainnet() && policyId == NEWM_TOKEN_POLICY && assetName == NEWM_TOKEN_NAME) ||
(!isMainnet() && policyId == NEWM_TOKEN_POLICY_TEST && assetName == NEWM_TOKEN_NAME_TEST)
) {
if (isNewmToken(policyId, assetName)) {
return queryNEWMUSDPrice()
}
throw IllegalArgumentException("Unsupported token for price API - policyId: $policyId, assetName: $assetName")
}

override suspend fun isNewmToken(
policyId: String,
assetName: String
): Boolean =
if (isMainnet()) {
policyId == NEWM_TOKEN_POLICY && assetName == NEWM_TOKEN_NAME
} else {
policyId == NEWM_TOKEN_POLICY_TEST && assetName == NEWM_TOKEN_NAME_TEST
}

override suspend fun snapshotToken(
policyId: String,
name: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package io.newm.server.features.marketplace.database
import io.newm.chain.util.assetFingerprintOf
import io.newm.chain.util.assetUrlOf
import io.newm.server.features.collaboration.database.CollaborationEntity
import io.newm.server.features.marketplace.model.CostAmountConversions
import io.newm.server.features.marketplace.model.Sale
import io.newm.server.features.marketplace.model.SaleFilters
import io.newm.server.features.marketplace.model.SaleStatus
Expand Down Expand Up @@ -65,7 +66,7 @@ class MarketplaceSaleEntity(
fun toModel(
isMainnet: Boolean,
isNftCdnEnabled: Boolean,
costAmountUsd: String
costAmountConvertions: CostAmountConversions
): Sale {
val song = SongEntity[songId]
val artist = UserEntity[song.ownerId]
Expand Down Expand Up @@ -100,7 +101,8 @@ class MarketplaceSaleEntity(
costPolicyId = costPolicyId,
costAssetName = costAssetName,
costAmount = costAmount,
costAmountUsd = costAmountUsd,
costAmountUsd = costAmountConvertions.usd,
costAmountNewm = costAmountConvertions.newm,
maxBundleSize = maxBundleSize,
totalBundleQuantity = totalBundleQuantity,
bundleAmount = bundleAmount,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package io.newm.server.features.marketplace.model

data class CostAmountConversions(
val usd: String,
val newm: String
)
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ data class Sale(
val costAssetName: String,
val costAmount: Long,
val costAmountUsd: String,
val costAmountNewm: String,
val maxBundleSize: Long,
val totalBundleQuantity: Long,
val availableBundleQuantity: Long,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import io.newm.server.features.marketplace.database.MarketplacePurchaseEntity
import io.newm.server.features.marketplace.database.MarketplaceSaleEntity
import io.newm.server.features.marketplace.model.Artist
import io.newm.server.features.marketplace.model.ArtistFilters
import io.newm.server.features.marketplace.model.CostAmountConversions
import io.newm.server.features.marketplace.model.OrderAmountRequest
import io.newm.server.features.marketplace.model.OrderAmountResponse
import io.newm.server.features.marketplace.model.OrderTransactionRequest
Expand Down Expand Up @@ -96,8 +97,8 @@ internal class MarketplaceRepositoryImpl(
val sale = transaction { MarketplaceSaleEntity[saleId] }
val isMainnet = cardanoRepository.isMainnet()
val isNftCdnEnabled = configRepository.getBoolean(CONFIG_KEY_NFTCDN_ENABLED)
val costAmountUsd = sale.getCostAmountUsd()
return transaction { sale.toModel(isMainnet, isNftCdnEnabled, costAmountUsd) }
val costAmountConversions = sale.computeCostAmountConversions()
return transaction { sale.toModel(isMainnet, isNftCdnEnabled, costAmountConversions) }
}

override suspend fun getSales(
Expand All @@ -111,9 +112,9 @@ internal class MarketplaceRepositoryImpl(
val sales = transaction {
MarketplaceSaleEntity.all(filters).limit(n = limit, offset = offset.toLong()).toList()
}
val costAmountsUsd: Map<UUID, String> = sales.associate { it.id.value to it.getCostAmountUsd() }
val costAmountConversions = sales.associate { it.id.value to it.computeCostAmountConversions() }
return transaction {
sales.map { it.toModel(isMainnet, isNftCdnEnabled, costAmountsUsd[it.id.value]!!) }
sales.map { it.toModel(isMainnet, isNftCdnEnabled, costAmountConversions[it.id.value]!!) }
}
}

Expand Down Expand Up @@ -748,12 +749,20 @@ internal class MarketplaceRepositoryImpl(
.firstOrNull()
?.get(SongTable.id)

private suspend fun MarketplaceSaleEntity.getCostAmountUsd(): String {
val unitPrice = if (costPolicyId == configRepository.getString(CONFIG_KEY_MARKETPLACE_USD_POLICY_ID)) {
1L
} else {
cardanoRepository.queryNativeTokenUSDPrice(costPolicyId, costAssetName)
private suspend fun MarketplaceSaleEntity.computeCostAmountConversions(): CostAmountConversions {
val newmUsdPrice = cardanoRepository.queryNEWMUSDPrice()
val costTokenUsdPrice = when {
// for USD, 1 rather that 1000000 to account for costAmount being in 12 instead of 6 decimal places
costPolicyId == configRepository.getString(CONFIG_KEY_MARKETPLACE_USD_POLICY_ID) -> 1L

cardanoRepository.isNewmToken(costPolicyId, costAssetName) -> newmUsdPrice

else -> cardanoRepository.queryNativeTokenUSDPrice(costPolicyId, costAssetName)
}
return (costAmount.toBigInteger() * unitPrice.toBigInteger()).toBigDecimal(12).toPlainString()
val costAmountUsd = costAmount.toBigInteger() * costTokenUsdPrice.toBigInteger()
return CostAmountConversions(
usd = costAmountUsd.toBigDecimal(12).toPlainString(),
newm = (costAmountUsd.toBigDecimal(6) / newmUsdPrice.toBigDecimal()).toPlainString()
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import io.newm.server.features.marketplace.database.MarketplaceArtistEntity
import io.newm.server.features.marketplace.database.MarketplaceSaleEntity
import io.newm.server.features.marketplace.database.MarketplaceSaleTable
import io.newm.server.features.marketplace.model.Artist
import io.newm.server.features.marketplace.model.CostAmountConversions
import io.newm.server.features.marketplace.model.Sale
import io.newm.server.features.marketplace.model.SaleStatus
import io.newm.server.features.model.CountResponse
Expand All @@ -45,6 +46,7 @@ import java.time.LocalDateTime
import java.time.temporal.ChronoUnit

private const val COST_TOKEN_USD_PRICE = 5000L
private const val NEWM_USD_PRICE = 2500L

class MarketplaceRoutesTests : BaseApplicationTests() {
@BeforeAll
Expand All @@ -55,6 +57,8 @@ class MarketplaceRoutesTests : BaseApplicationTests() {
mockk<CardanoRepository>(relaxed = true) {
coEvery { isMainnet() } returns false
coEvery { queryNativeTokenUSDPrice(any(), any()) } returns COST_TOKEN_USD_PRICE
coEvery { queryNEWMUSDPrice() } returns NEWM_USD_PRICE
coEvery { isNewmToken(any(), any()) } returns false
}
}
single {
Expand Down Expand Up @@ -1009,6 +1013,8 @@ class MarketplaceRoutesTests : BaseApplicationTests() {
}
}

val costAmount = (offset + 1L) * 1234567L
val costAmountUsd = costAmount.toBigInteger() * COST_TOKEN_USD_PRICE.toBigInteger()
return transaction {
MarketplaceSaleEntity
.new {
Expand All @@ -1023,16 +1029,17 @@ class MarketplaceRoutesTests : BaseApplicationTests() {
bundleAmount = offset + 1L
costPolicyId = "costPolicyId$offset"
costAssetName = "costAssetName$offset"
costAmount = offset.toLong()
this.costAmount = costAmount
maxBundleSize = offset + 100L
totalBundleQuantity = offset + 1000L
availableBundleQuantity = offset + 1000L
}.toModel(
isMainnet = false,
isNftCdnEnabled = false,
costAmountUsd = (offset.toBigInteger() * COST_TOKEN_USD_PRICE.toBigInteger())
.toBigDecimal(12)
.toPlainString()
costAmountConvertions = CostAmountConversions(
usd = costAmountUsd.toBigDecimal(12).toPlainString(),
newm = (costAmountUsd.toBigDecimal(6) / NEWM_USD_PRICE.toBigDecimal()).toPlainString()
)
)
}
}
Expand Down

0 comments on commit aba6a6f

Please sign in to comment.