diff --git a/build.gradle.kts b/build.gradle.kts index 6e3e08b5e..c925cb25a 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -51,7 +51,7 @@ allprojects { } group = "exchange.dydx.abacus" -version = "1.7.42" +version = "1.7.44" repositories { google() diff --git a/docs/Input/TransferInput.md b/docs/Input/TransferInput.md index 416c53dcb..46729a4c8 100644 --- a/docs/Input/TransferInput.md +++ b/docs/Input/TransferInput.md @@ -7,7 +7,10 @@ data class TransferInput(  val fee: Double?,  val chain: String?,  val address: String?, + val memo: String?,  val depositOptions: DepositInputOptions?, + val withdrawalOptions: WithdrawalInputOptions?, + val transferOutOptions: TransferOutInputOptions?,  val summary: TransferInputSummary?,  val resources: TransferInputResources?,  val requestPayload: TransferInputRequestPayload? @@ -39,10 +42,22 @@ Selected chain to perform the transfer Selected token address of the chain to perform the transfer +## memo + +Memo for transfer + ## depositOptions structure of [DepositInputOptions](#DepositInputOptions) +## withdrawalOptions + +structure of [WithdrawalInputOptions](#WithdrawalInputOptions) + +## transferOutOptions + +structure of [TransferOutInputOptions](#TransferOutInputOptions) + ## summary structure of [TransferInputSummary](#TransferInputSummary) @@ -80,6 +95,66 @@ UX should let the user choose whether to use fast speed Option of assets to choose from +# WithdrawalInputOptions + +data class DepositInputOptions( + val needsSize: Boolean?, + val needsAddress: Boolean?, + val needsFastSpeed: Boolean?, + val exchanges: Array? + val chains: Array? + val assets: Array? +) + +## needsSize + +UX should let user enter the size + +## needsAddress + +UX should let user enter a wallet address + +## needsFastSpeed + +UX should let the user choose whether to use fast speed + +## exchanges + +Option of exchanges to choose from + +## chains + +Option of chains to choose from + +## assets + +Option of assets to choose from + +# TransferOutInputOptions + +data class TransferOutInputOptions( + val needsSize: Boolean?, + val needsAddress: Boolean?, + val chains: Array?, + val assets: Array? +) + +## needsSize + +UX should let user enter the size + +## needsAddress + +UX should let user enter a wallet address + +## chains + +Option of chains to choose from + +## assets + +Option of assets to choose from + # TransferInputSummary data class TransferInputSummary( @@ -102,7 +177,7 @@ Whether the transfer transaction can be filled # TransferInputResources -The chain and token resources of the selected chain and its associated tokens. Use the chainId +The chain and token resources of the selected chain and its associated tokens. Use the chainId and token address of the key to the maps, respectively, to get the resource. data class TransferInputResources( @@ -147,4 +222,4 @@ data class TransferInputRequestPayload(  val gasPrice: String?,  val maxFeePerGas: String?,  val maxPriorityFeePerGas: String? -) \ No newline at end of file +) diff --git a/src/commonMain/kotlin/exchange.dydx.abacus/output/input/TransferInput.kt b/src/commonMain/kotlin/exchange.dydx.abacus/output/input/TransferInput.kt index bca5f610e..5c49f6dd4 100644 --- a/src/commonMain/kotlin/exchange.dydx.abacus/output/input/TransferInput.kt +++ b/src/commonMain/kotlin/exchange.dydx.abacus/output/input/TransferInput.kt @@ -149,7 +149,7 @@ data class TransferOutInputOptions( val needsSize: Boolean?, val needsAddress: Boolean?, val chains: IList?, - val assets: IList? + val assets: IList?, ) { companion object { internal fun create( @@ -474,6 +474,7 @@ data class TransferInput( val chain: String?, val token: String?, val address: String?, + val memo: String?, val depositOptions: DepositInputOptions?, val withdrawalOptions: WithdrawalInputOptions?, val transferOutOptions: TransferOutInputOptions?, @@ -509,6 +510,7 @@ data class TransferInput( val chain = parser.asString(data["chain"]) val token = parser.asString(data["token"]) val address = parser.asString(data["address"]) + val memo = parser.asString(data["memo"]) var depositOptions: DepositInputOptions? = null if (type == TransferType.deposit) { @@ -577,6 +579,7 @@ data class TransferInput( existing.chain != chain || existing.token != token || existing.address != address || + existing.memo != memo || existing.depositOptions != depositOptions || existing.withdrawalOptions != withdrawalOptions || existing.transferOutOptions != transferOutOptions || @@ -595,6 +598,7 @@ data class TransferInput( chain, token, address, + memo, depositOptions, withdrawalOptions, transferOutOptions, diff --git a/src/commonMain/kotlin/exchange.dydx.abacus/processor/router/IRouterProcessor.kt b/src/commonMain/kotlin/exchange.dydx.abacus/processor/router/IRouterProcessor.kt index 8e8d48f5a..010188635 100644 --- a/src/commonMain/kotlin/exchange.dydx.abacus/processor/router/IRouterProcessor.kt +++ b/src/commonMain/kotlin/exchange.dydx.abacus/processor/router/IRouterProcessor.kt @@ -1,5 +1,9 @@ package exchange.dydx.abacus.processor.router +import exchange.dydx.abacus.output.input.SelectionOption +import exchange.dydx.abacus.output.input.TransferInputChainResource +import exchange.dydx.abacus.output.input.TransferInputTokenResource + interface IRouterProcessor { var tokens: List? var chains: List? @@ -44,8 +48,8 @@ interface IRouterProcessor { fun selectedTokenDecimals(tokenAddress: String?, selectedChainId: String?): String? fun filteredTokens(chainId: String?): List? fun defaultTokenAddress(chainId: String?): String? - fun chainResources(chainId: String?): Map? - fun tokenResources(chainId: String?): Map? + fun chainResources(chainId: String?): Map? + fun tokenResources(chainId: String?): Map? fun chainOptions(): List - fun tokenOptions(chainId: String?): List + fun tokenOptions(chainId: String?): List } diff --git a/src/commonMain/kotlin/exchange.dydx.abacus/processor/router/squid/SquidProcessor.kt b/src/commonMain/kotlin/exchange.dydx.abacus/processor/router/squid/SquidProcessor.kt index f1d7c1e40..c0362a6be 100644 --- a/src/commonMain/kotlin/exchange.dydx.abacus/processor/router/squid/SquidProcessor.kt +++ b/src/commonMain/kotlin/exchange.dydx.abacus/processor/router/squid/SquidProcessor.kt @@ -173,6 +173,8 @@ internal class SquidProcessor( override fun updateTokensDefaults(modified: MutableMap, 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) } diff --git a/src/commonMain/kotlin/exchange.dydx.abacus/state/model/TradingStateMachine+TransferInput.kt b/src/commonMain/kotlin/exchange.dydx.abacus/state/model/TradingStateMachine+TransferInput.kt index 86fe4ff29..e9391f86e 100644 --- a/src/commonMain/kotlin/exchange.dydx.abacus/state/model/TradingStateMachine+TransferInput.kt +++ b/src/commonMain/kotlin/exchange.dydx.abacus/state/model/TradingStateMachine+TransferInput.kt @@ -25,6 +25,7 @@ enum class TransferInputField(val rawValue: String) { chain("chain"), token("token"), address("address"), + MEMO("memo"), fastSpeed("fastSpeed"); companion object { @@ -69,6 +70,7 @@ fun TradingStateMachine.transfer( transfer.safeSet("size.usdcSize", null) transfer.safeSet("route", null) transfer.safeSet("requestPayload", null) + transfer.safeSet("memo", null) if (parser.asString(data) == "TRANSFER_OUT") { transfer.safeSet("chain", "chain") transfer.safeSet("token", "usdc") @@ -135,7 +137,6 @@ fun TradingStateMachine.transfer( iListOf(subaccountNumber), ) } - TransferInputField.fastSpeed.rawValue -> { transfer.safeSet(typeText, parser.asBool(data)) changes = StateChanges( @@ -166,6 +167,14 @@ fun TradingStateMachine.transfer( iListOf(subaccountNumber), ) } + TransferInputField.MEMO.rawValue -> { + transfer.safeSet(typeText, parser.asString(data)) + changes = StateChanges( + iListOf(Changes.input), + null, + iListOf(subaccountNumber), + ) + } else -> {} } } else { @@ -205,35 +214,44 @@ private fun TradingStateMachine.updateTransferToTokenType(transfer: MutableMap, chainType: String) { val tokenOptions = routerProcessor.tokenOptions(chainType) if (transfer["type"] != "TRANSFER_OUT") { - transfer.safeSet( - "depositOptions.assets", - tokenOptions, - ) - transfer.safeSet( - "withdrawalOptions.assets", - tokenOptions, - ) + internalState.transfer.tokens = tokenOptions transfer.safeSet("chain", chainType) transfer.safeSet("token", routerProcessor.defaultTokenAddress(chainType)) - transfer.safeSet( - "resources.chainResources", - routerProcessor.chainResources(chainType), - ) - transfer.safeSet( - "resources.tokenResources", - routerProcessor.tokenResources(chainType), - ) + internalState.transfer.chainResources = routerProcessor.chainResources(chainType) + internalState.transfer.tokenResources = routerProcessor.tokenResources(chainType) } transfer.safeSet("exchange", null) transfer.safeSet("size.size", null) transfer.safeSet("route", null) transfer.safeSet("requestPayload", null) +// needed to pass tests, remove later + transfer.safeSet( + "depositOptions.assets", + tokenOptions, + ) + transfer.safeSet( + "withdrawalOptions.assets", + tokenOptions, + ) + transfer.safeSet( + "resources.chainResources", + routerProcessor.chainResources(chainType), + ) + transfer.safeSet( + "resources.tokenResources", + routerProcessor.tokenResources(chainType), + ) } private fun TradingStateMachine.updateTransferExchangeType(transfer: MutableMap, exchange: String) { val exchangeDestinationChainId = routerProcessor.exchangeDestinationChainId val tokenOptions = routerProcessor.tokenOptions(exchangeDestinationChainId) if (transfer["type"] != "TRANSFER_OUT") { + internalState.transfer.tokens = tokenOptions + transfer.safeSet("token", routerProcessor.defaultTokenAddress(exchangeDestinationChainId)) + internalState.transfer.tokenResources = routerProcessor.tokenResources(exchangeDestinationChainId) + +// needed to pass tests, remove later transfer.safeSet( "depositOptions.assets", tokenOptions, @@ -242,7 +260,6 @@ private fun TradingStateMachine.updateTransferExchangeType(transfer: MutableMap< "withdrawalOptions.assets", tokenOptions, ) - transfer.safeSet("token", routerProcessor.defaultTokenAddress(exchangeDestinationChainId)) transfer.safeSet( "resources.tokenResources", routerProcessor.tokenResources(exchangeDestinationChainId), diff --git a/src/commonMain/kotlin/exchange.dydx.abacus/state/model/TradingStateMachine.kt b/src/commonMain/kotlin/exchange.dydx.abacus/state/model/TradingStateMachine.kt index c954b4db4..8e599f727 100644 --- a/src/commonMain/kotlin/exchange.dydx.abacus/state/model/TradingStateMachine.kt +++ b/src/commonMain/kotlin/exchange.dydx.abacus/state/model/TradingStateMachine.kt @@ -86,7 +86,7 @@ open class TradingStateMachine( private val useParentSubaccount: Boolean, private val routerVendor: OnboardingConfigs.RouterVendor, ) { - private val internalState: InternalState = InternalState() + internal val internalState: InternalState = InternalState() internal val parser: ParserProtocol = Parser() internal val marketsProcessor = MarketsSummaryProcessor(parser) diff --git a/src/commonTest/kotlin/exchange.dydx.abacus/payload/TransferInputTests.kt b/src/commonTest/kotlin/exchange.dydx.abacus/payload/TransferInputTests.kt index d86937fbc..633528067 100644 --- a/src/commonTest/kotlin/exchange.dydx.abacus/payload/TransferInputTests.kt +++ b/src/commonTest/kotlin/exchange.dydx.abacus/payload/TransferInputTests.kt @@ -28,6 +28,8 @@ class TransferInputTests : V3BaseTests() { testTransferOutTransferInput() perp.log("Transfer Out", time) + + testTransferInputTypeChange() } private fun testDepositTransferInput() { @@ -414,6 +416,10 @@ class TransferInputTests : V3BaseTests() { perp.transfer("5000.0", TransferInputField.usdcSize) }, null) + test({ + perp.transfer("test memo", TransferInputField.MEMO) + }, null) + test( { perp.transfer("1000.0", TransferInputField.usdcSize) @@ -423,6 +429,7 @@ class TransferInputTests : V3BaseTests() { "input": { "transfer": { "type": "TRANSFER_OUT", + "memo": "test memo", "size": { "usdcSize": 1000.0 }, @@ -469,4 +476,70 @@ class TransferInputTests : V3BaseTests() { }, ) } + + private fun testTransferInputTypeChange() { + test( + { + perp.transfer("DEPOSIT", TransferInputField.type) + }, + """ + { + "input": { + "transfer": { + "type": "DEPOSIT", + "memo": null + } + } + } + """.trimIndent(), + ) + + test( + { + perp.transfer("TRANSFER_OUT", TransferInputField.type) + }, + """ + { + "input": { + "transfer": { + "type": "TRANSFER_OUT", + "memo": null + } + } + } + """.trimIndent(), + ) + + test( + { + perp.transfer("test memo", TransferInputField.MEMO) + }, + """ + { + "input": { + "transfer": { + "type": "TRANSFER_OUT", + "memo": "test memo" + } + } + } + """.trimIndent(), + ) + + test( + { + perp.transfer("WITHDRAWAL", TransferInputField.type) + }, + """ + { + "input": { + "transfer": { + "type": "WITHDRAWAL", + "memo": null + } + } + } + """.trimIndent(), + ) + } } diff --git a/v4_abacus.podspec b/v4_abacus.podspec index 9cc9897c9..c63d69bbf 100644 --- a/v4_abacus.podspec +++ b/v4_abacus.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |spec| spec.name = 'v4_abacus' - spec.version = '1.7.42' + spec.version = '1.7.44' spec.homepage = 'https://github.com/dydxprotocol/v4-abacus' spec.source = { :http=> ''} spec.authors = ''