Skip to content

Commit

Permalink
Merge branch 'main' into feature/TRA-329-trade-isolated-margin-receip…
Browse files Browse the repository at this point in the history
…t-lines-liquidation-price
  • Loading branch information
johnqh committed May 31, 2024
2 parents b4e2c06 + 82f7f6d commit cac69a6
Show file tree
Hide file tree
Showing 13 changed files with 361 additions and 52 deletions.
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ allprojects {
}

group = "exchange.dydx.abacus"
version = "1.7.43"
version = "1.7.44"

repositories {
google()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,8 @@ data class TransferOutInputOptions(
@Serializable
data class TransferInputChainResource(
val chainName: String?,
val rpc: String?,
val networkName: String?,
val rpc: String? = null,
val networkName: String? = null,
val chainId: Int?,
val iconUrl: String?
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
package exchange.dydx.abacus.processor.router.skip

import exchange.dydx.abacus.processor.base.BaseProcessor
import exchange.dydx.abacus.output.input.SelectionOption
import exchange.dydx.abacus.protocols.ParserProtocol

internal class SkipChainProcessor(parser: ParserProtocol) : BaseProcessor(parser) {
private val keyMap = mapOf(
"string" to mapOf(
"chain_name" to "stringKey",
"networkIdentifier" to "stringKey",
"chain_id" to "type",
"logo_uri" to "iconUrl",
),
)

override fun received(
existing: Map<String, Any>?,
internal class SkipChainProcessor(private val parser: ParserProtocol) {
fun received(
payload: Map<String, Any>
): Map<String, Any> {
return transform(existing, payload, keyMap)
): SelectionOption {
return SelectionOption(
stringKey = parser.asString(payload["network_identifier"]) ?: parser.asString(payload["chain_name"]),
string = parser.asString(payload["network_identifier"]) ?: parser.asString(payload["chain_name"]),
type = parser.asString(payload["chain_id"]) ?: "",
iconUrl = parser.asString(payload["logo_uri"]),
)
}
}
Original file line number Diff line number Diff line change
@@ -1,23 +1,19 @@
package exchange.dydx.abacus.processor.router.skip

import exchange.dydx.abacus.processor.base.BaseProcessor
import exchange.dydx.abacus.output.input.TransferInputChainResource
import exchange.dydx.abacus.protocols.ParserProtocol

internal class SkipChainResourceProcessor(parser: ParserProtocol) : BaseProcessor(parser) {
private val keyMap = mapOf(
"string" to mapOf(
"chain_name" to "chainName",
"rpc" to "rpc",
"networkName" to "networkName",
"chain_id" to "chainId",
"logo_uri" to "iconUrl",
),
)
internal class SkipChainResourceProcessor(private val parser: ParserProtocol) {

override fun received(
existing: Map<String, Any>?,
fun received(
payload: Map<String, Any>
): Map<String, Any> {
return transform(existing, payload, keyMap)
): TransferInputChainResource {
return TransferInputChainResource(
chainName = parser.asString(payload["chain_name"]),
rpc = parser.asString(payload["rpc"]),
networkName = parser.asString(payload["networkName"]),
chainId = parser.asInt(payload["chain_id"]),
iconUrl = parser.asString(payload["logo_uri"]),
)
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
package exchange.dydx.abacus.processor.router.skip

import exchange.dydx.abacus.output.input.SelectionOption
import exchange.dydx.abacus.output.input.TransferInputChainResource
import exchange.dydx.abacus.processor.base.BaseProcessor
import exchange.dydx.abacus.processor.router.IRouterProcessor
import exchange.dydx.abacus.processor.router.SharedRouterProcessor
import exchange.dydx.abacus.protocols.ParserProtocol
import exchange.dydx.abacus.state.internalstate.InternalTransferInputState
import exchange.dydx.abacus.utils.mutable
import exchange.dydx.abacus.utils.safeSet

@Suppress("NotImplementedDeclaration")
internal class SkipProcessor(parser: ParserProtocol) : BaseProcessor(parser), IRouterProcessor {
internal class SkipProcessor(
parser: ParserProtocol,
private val internalState: InternalTransferInputState
) : BaseProcessor(parser), IRouterProcessor {
override var chains: List<Any>? = null

// possibly want to use a different variable so we aren't stuck with this bad type
Expand All @@ -26,8 +33,25 @@ internal class SkipProcessor(parser: ParserProtocol) : BaseProcessor(parser), IR
existing: Map<String, Any>?,
payload: Map<String, Any>
): Map<String, Any>? {
throw NotImplementedError("receivedChains is not implemented in SkipProcessor!")
if (this.chains != null) {
return existing
}
this.chains = parser.asNativeList(payload["chains"])
var modified = mutableMapOf<String, Any>()
existing?.let {
modified = it.mutable()
}
val chainOptions = chainOptions()

internalState.chains = chainOptions
val selectedChainId = defaultChainId()
modified.safeSet("transfer.chain", selectedChainId)
selectedChainId?.let {
internalState.chainResources = chainResources(chainId = selectedChainId)
}
return modified
}

override fun receivedTokens(
existing: Map<String, Any>?,
payload: Map<String, Any>
Expand Down Expand Up @@ -72,7 +96,9 @@ internal class SkipProcessor(parser: ParserProtocol) : BaseProcessor(parser), IR
}

override fun defaultChainId(): String? {
throw NotImplementedError("defaultChainId is not implemented in SkipProcessor!")
val selectedChain = parser.asNativeMap(this.chains?.find { parser.asString(parser.asNativeMap(it)?.get("chain_id")) == "1" })

return parser.asString(selectedChain?.get("chain_id"))
}

override fun selectedTokenSymbol(tokenAddress: String?): String? {
Expand All @@ -91,16 +117,41 @@ internal class SkipProcessor(parser: ParserProtocol) : BaseProcessor(parser), IR
throw NotImplementedError("defaultTokenAddress is not implemented in SkipProcessor!")
}

override fun chainResources(chainId: String?): Map<String, Any>? {
throw NotImplementedError("chainResources is not implemented in SkipProcessor!")
override fun chainResources(chainId: String?): Map<String, TransferInputChainResource>? {
val chainResources = mutableMapOf<String, TransferInputChainResource>()
chainId?.let {
this.chains?.find {
parser.asString(parser.asNativeMap(it)?.get("chain_id")) == chainId
}?.let {
val processor = SkipChainResourceProcessor(parser)
parser.asNativeMap(it)?.let { payload ->
chainResources[chainId] = processor.received(payload)
}
}
}
return chainResources
}

override fun tokenResources(chainId: String?): Map<String, Any>? {
throw NotImplementedError("tokenResources is not implemented in SkipProcessor!")
}

override fun chainOptions(): List<Any> {
throw NotImplementedError("chainOptions is not implemented in SkipProcessor!")
override fun chainOptions(): List<SelectionOption> {
val chainProcessor = SkipChainProcessor(parser)
val options = mutableListOf<SelectionOption>()

this.chains?.let {
for (chain in it) {
parser.asNativeMap(chain)?.let { chain ->
if (parser.asString(chain.get("chainType")) != "cosmos") {
options.add(chainProcessor.received(chain))
}
}
}
}

options.sortBy { parser.asString(it.stringKey) }
return options
}

override fun tokenOptions(chainId: String?): List<Any> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,8 @@ internal class SquidProcessor(
override fun updateTokensDefaults(modified: MutableMap<String, Any>, selectedChainId: String?) {
val tokenOptions = tokenOptions(selectedChainId)
internalState.tokens = tokenOptions
modified.safeSet("transfer.depositOptions.assets", tokenOptions)
modified.safeSet("transfer.withdrawalOptions.assets", tokenOptions)
modified.safeSet("transfer.token", defaultTokenAddress(selectedChainId))
internalState.tokenResources = tokenResources(selectedChainId)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,19 @@ class V4StateManagerConfigs(
return if (environment.isMainNet) "noble-1" else "grand-1"
}

fun skipV1Chains(): String {
return "$skipHost/v1/info/chains?include_evm=true"
}

fun nobleDenom(): String? {
return "uusdc"
}

private val skipHost: String
get() {
return "https://api.skip.money"
}

private val squidV2Host: String
get() {
return if (environment.isMainNet) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import kollections.iListOf
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.jsonObject

internal fun TradingStateMachine.squidChains(payload: String): StateChanges? {
internal fun TradingStateMachine.routerChains(payload: String): StateChanges? {
val json = parser.decodeJsonObject(payload)
return if (json != null) {
input = squidProcessor.receivedChains(input, json)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import exchange.dydx.abacus.state.manager.HumanReadableWithdrawPayload
import exchange.dydx.abacus.state.manager.pendingCctpWithdraw
import exchange.dydx.abacus.state.model.TradingStateMachine
import exchange.dydx.abacus.state.model.TransferInputField
import exchange.dydx.abacus.state.model.routerChains
import exchange.dydx.abacus.state.model.squidRoute
import exchange.dydx.abacus.state.model.squidRouteV2
import exchange.dydx.abacus.state.model.squidStatus
Expand Down Expand Up @@ -69,6 +70,17 @@ internal class OnboardingSupervisor(
retrieveCctpChainIds()
}

@Suppress("UnusedPrivateMember")
private fun retrieveSkipTransferChains() {
val oldState = stateMachine.state
val chainsUrl = helper.configs.skipV1Chains()
helper.get(chainsUrl, null, null) { _, response, httpCode, _ ->
if (helper.success(httpCode) && response != null) {
update(stateMachine.routerChains(response), oldState)
}
}
}

private fun retrieveTransferAssets() {
val oldState = stateMachine.state
val url = helper.configs.squidV2Assets()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package exchange.dydx.abacus.payload.v4

import exchange.dydx.abacus.state.model.TransferInputField
import exchange.dydx.abacus.state.model.squidChains
import exchange.dydx.abacus.state.model.routerChains
import exchange.dydx.abacus.state.model.squidRoute
import exchange.dydx.abacus.state.model.squidRouteV2
import exchange.dydx.abacus.state.model.squidStatus
Expand All @@ -20,7 +20,7 @@ class V4SquidTests : V4BaseTests() {
// Due to the JIT compiler nature for JVM (and Kotlin) and JS, Android/web would ran slow the first round. Second round give more accurate result
setup()

val stateChange = perp.squidChains(mock.squidChainsMock.payload)
val stateChange = perp.routerChains(mock.squidChainsMock.payload)
assertNotNull(stateChange)

test({
Expand All @@ -47,7 +47,7 @@ class V4SquidTests : V4BaseTests() {
// Due to the JIT compiler nature for JVM (and Kotlin) and JS, Android/web would ran slow the first round. Second round give more accurate result
setup()

var stateChange = perp.squidChains(mock.squidChainsMock.payload)
var stateChange = perp.routerChains(mock.squidChainsMock.payload)
assertNotNull(stateChange)

stateChange = perp.squidTokens(mock.squidTokensMock.payload)
Expand Down Expand Up @@ -112,7 +112,7 @@ class V4SquidTests : V4BaseTests() {

perp.transfer("DEPOSIT", TransferInputField.type, 0)

var stateChange = perp.squidChains(mock.squidChainsMock.payload)
var stateChange = perp.routerChains(mock.squidChainsMock.payload)
assertNotNull(stateChange)

stateChange = perp.squidTokens(mock.squidTokensMock.payload)
Expand Down Expand Up @@ -148,7 +148,7 @@ class V4SquidTests : V4BaseTests() {

perp.transfer("DEPOSIT", TransferInputField.type, 0)

var stateChange = perp.squidChains(mock.squidChainsMock.payload)
var stateChange = perp.routerChains(mock.squidChainsMock.payload)
assertNotNull(stateChange)

stateChange = perp.squidTokens(mock.squidTokensMock.payload)
Expand Down Expand Up @@ -219,7 +219,7 @@ class V4SquidTests : V4BaseTests() {
fun testDefaultTokenAddress() {
setup()

var stateChange = perp.squidChains(mock.squidChainsMock.payload)
var stateChange = perp.routerChains(mock.squidChainsMock.payload)
assertNotNull(stateChange)

stateChange = perp.squidTokens(mock.squidTokensMock.payload)
Expand All @@ -232,7 +232,7 @@ class V4SquidTests : V4BaseTests() {
fun testChainResources() {
setup()

val stateChange = perp.squidChains(mock.squidChainsMock.payload)
val stateChange = perp.routerChains(mock.squidChainsMock.payload)
assertNotNull(stateChange)

val result = perp.squidProcessor.chainResources("1")
Expand All @@ -245,7 +245,7 @@ class V4SquidTests : V4BaseTests() {
fun testTokenResources() {
setup()

var stateChange = perp.squidChains(mock.squidChainsMock.payload)
var stateChange = perp.routerChains(mock.squidChainsMock.payload)
assertNotNull(stateChange)

stateChange = perp.squidTokens(mock.squidTokensMock.payload)
Expand All @@ -259,7 +259,7 @@ class V4SquidTests : V4BaseTests() {
fun testTokenOptions() {
setup()

var stateChange = perp.squidChains(mock.squidChainsMock.payload)
var stateChange = perp.routerChains(mock.squidChainsMock.payload)
assertNotNull(stateChange)

stateChange = perp.squidTokens(mock.squidTokensMock.payload)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package exchange.dydx.abacus.processor.router.skip
import exchange.dydx.abacus.output.input.SelectionOption
import exchange.dydx.abacus.output.input.TransferInputChainResource
import exchange.dydx.abacus.state.internalstate.InternalTransferInputState
import exchange.dydx.abacus.tests.payloads.SkipChainsMock
import exchange.dydx.abacus.utils.Parser
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.jsonObject
import kotlin.test.Test
import kotlin.test.assertEquals

internal fun templateToJson(template: String): Map<String, Any> {
return Json.parseToJsonElement(template.trimIndent()).jsonObject.toMap()
}

class SkipProcessorTests {

internal val internalState = InternalTransferInputState()
internal val skipProcessor = SkipProcessor(parser = Parser(), internalState = internalState)
internal val skipChainsMock = SkipChainsMock()

@Test
fun testReceivedChains() {
val modified = skipProcessor.receivedChains(
existing = mapOf(),
payload = templateToJson(
skipChainsMock.payload,
),
)

val expectedChains = listOf(
SelectionOption(stringKey = "Ethereum", string = "Ethereum", type = "1", iconUrl = "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/info/logo.png"),
SelectionOption(stringKey = "aura", string = "aura", type = "xstaxy-1", iconUrl = "https://raw.githubusercontent.com/chainapsis/keplr-chain-registry/main/images/xstaxy/chain.png"),
SelectionOption(stringKey = "cheqd", string = "cheqd", type = "cheqd-mainnet-1", iconUrl = "https://raw.githubusercontent.com/chainapsis/keplr-chain-registry/main/images/cheqd-mainnet/chain.png"),
SelectionOption(stringKey = "kujira", string = "kujira", type = "kaiyo-1", iconUrl = "https://raw.githubusercontent.com/chainapsis/keplr-chain-registry/main/images/kaiyo/chain.png"),
SelectionOption(stringKey = "osmosis", string = "osmosis", type = "osmosis-1", iconUrl = "https://raw.githubusercontent.com/chainapsis/keplr-chain-registry/main/images/osmosis/chain.png"),
SelectionOption(stringKey = "stride", string = "stride", type = "stride-1", iconUrl = "https://raw.githubusercontent.com/chainapsis/keplr-chain-registry/main/images/stride/chain.png"),
)
assertEquals(expectedChains, internalState.chains)

val expectedChainResources = mapOf(
"1" to TransferInputChainResource(
chainName = "Ethereum",
chainId = 1,
iconUrl = "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/info/logo.png",
),
)
assertEquals(expectedChainResources, internalState.chainResources)

val expectedModified = mapOf(
"transfer" to mapOf(
"chain" to "1",
),
)
assertEquals(expectedModified, modified)
}
}
Loading

0 comments on commit cac69a6

Please sign in to comment.