diff --git a/app/src/main/java/io/gnosis/safe/ui/transactions/TransactionListViewHolderFactory.kt b/app/src/main/java/io/gnosis/safe/ui/transactions/TransactionListViewHolderFactory.kt index 2a5324ea1..42ca97bc6 100644 --- a/app/src/main/java/io/gnosis/safe/ui/transactions/TransactionListViewHolderFactory.kt +++ b/app/src/main/java/io/gnosis/safe/ui/transactions/TransactionListViewHolderFactory.kt @@ -43,6 +43,10 @@ enum class TransactionViewType { REJECTION_QUEUED, SWAP_ORDER, SWAP_ORDER_QUEUED, + SWAP_TRANSFER, + SWAP_TRANSFER_QUEUED, + TWAP_ORDER, + TWAP_ORDER_QUEUED, CONFLICT } @@ -66,6 +70,10 @@ class TransactionViewHolderFactory : BaseFactory RejectionQueuedViewHolder(viewBinding as ItemTxQueuedRejectionBinding) TransactionViewType.SWAP_ORDER.ordinal -> SwapOrderViewHolder(viewBinding as ItemTxSwapOrderBinding) TransactionViewType.SWAP_ORDER_QUEUED.ordinal -> SwapOrderQueuedViewHolder(viewBinding as ItemTxQueuedSwapOrderBinding) + TransactionViewType.SWAP_TRANSFER.ordinal -> SwapTransferViewHolder(viewBinding as ItemTxSwapOrderBinding) + TransactionViewType.SWAP_TRANSFER_QUEUED.ordinal -> SwapTransferQueuedViewHolder(viewBinding as ItemTxQueuedSwapOrderBinding) + TransactionViewType.TWAP_ORDER.ordinal -> TwapOrderViewHolder(viewBinding as ItemTxSwapOrderBinding) + TransactionViewType.TWAP_ORDER_QUEUED.ordinal -> TwapOrderQueuedViewHolder(viewBinding as ItemTxQueuedSwapOrderBinding) else -> throw UnsupportedViewType(javaClass.name) } as BaseTransactionViewHolder @@ -86,6 +94,11 @@ class TransactionViewHolderFactory : BaseFactory ItemTxQueuedRejectionBinding.inflate(layoutInflater, parent, false) TransactionViewType.SWAP_ORDER.ordinal -> ItemTxSwapOrderBinding.inflate(layoutInflater, parent, false) TransactionViewType.SWAP_ORDER_QUEUED.ordinal -> ItemTxQueuedSwapOrderBinding.inflate(layoutInflater, parent, false) + TransactionViewType.SWAP_TRANSFER.ordinal -> ItemTxSwapOrderBinding.inflate(layoutInflater, parent, false) + TransactionViewType.SWAP_TRANSFER_QUEUED.ordinal -> ItemTxQueuedSwapOrderBinding.inflate(layoutInflater, parent, false) + TransactionViewType.TWAP_ORDER.ordinal -> ItemTxSwapOrderBinding.inflate(layoutInflater, parent, false) + TransactionViewType.TWAP_ORDER_QUEUED.ordinal -> ItemTxQueuedSwapOrderBinding.inflate(layoutInflater, parent, false) + else -> throw UnsupportedViewType(javaClass.name) } @@ -107,6 +120,10 @@ class TransactionViewHolderFactory : BaseFactory TransactionViewType.REJECTION_QUEUED is TransactionView.SwapOrderTransaction -> TransactionViewType.SWAP_ORDER is TransactionView.SwapOrderTransactionQueued -> TransactionViewType.SWAP_ORDER_QUEUED + is TransactionView.SwapTransferTransaction -> TransactionViewType.SWAP_TRANSFER + is TransactionView.SwapTransferTransactionQueued -> TransactionViewType.SWAP_TRANSFER_QUEUED + is TransactionView.TwapOrderTransaction -> TransactionViewType.TWAP_ORDER + is TransactionView.TwapOrderTransactionQueued -> TransactionViewType.TWAP_ORDER_QUEUED }.ordinal } @@ -382,6 +399,119 @@ class SwapOrderViewHolder(private val viewBinding: ItemTxSwapOrderBinding) : } } +class SwapTransferQueuedViewHolder(private val viewBinding: ItemTxQueuedSwapOrderBinding) : + BaseTransactionViewHolder(viewBinding) { + + @OptIn(ExperimentalTime::class) + override fun bind(viewTransfer: TransactionView.SwapTransferTransactionQueued, payloads: List) { + val resources = viewBinding.root.context.resources + val theme = viewBinding.root.context.theme + + with(viewBinding) { + status.setText(viewTransfer.statusText) + status.setTextColor(ResourcesCompat.getColor(resources, viewTransfer.statusColorRes, theme)) + + dateTime.text = viewTransfer.dateTime.elapsedIntervalTo(Date.from(Instant.now())).format(resources) + addressName.text = resources.getString(R.string.tx_list_swap_transfer) + + confirmationsIcon.setImageDrawable(ResourcesCompat.getDrawable(resources, viewTransfer.confirmationsIcon, theme)) + confirmations.setTextColor(ResourcesCompat.getColor(resources, viewTransfer.confirmationsTextColor, theme)) + confirmations.text = resources.getString(R.string.tx_list_confirmations, viewTransfer.confirmations, viewTransfer.threshold) + + nonce.text = viewTransfer.nonce + + root.setOnClickListener { + navigateToTxDetails(it, viewTransfer.chain, viewTransfer.id) + } + } + } +} + +class SwapTransferViewHolder(private val viewBinding: ItemTxSwapOrderBinding) : + BaseTransactionViewHolder(viewBinding) { + + override fun bind(viewTransfer: TransactionView.SwapTransferTransaction, payloads: List) { + val resources = viewBinding.root.context.resources + val theme = viewBinding.root.context.theme + + with(viewBinding) { + finalStatus.setText(viewTransfer.statusText) + finalStatus.setTextColor(ResourcesCompat.getColor(resources, viewTransfer.statusColorRes, theme)) + dateTime.text = viewTransfer.dateTimeText + + nonce.text = viewTransfer.nonce + addressName.text = resources.getString(R.string.tx_list_swap_transfer) + + addressLogo.alpha = viewTransfer.alpha + addressName.alpha = viewTransfer.alpha + finalStatus.alpha = OPACITY_FULL + dateTime.alpha = viewTransfer.alpha + nonce.alpha = viewTransfer.alpha + + root.setOnClickListener { + navigateToTxDetails(it, viewTransfer.chain, viewTransfer.id) + } + } + } +} + +class TwapOrderQueuedViewHolder(private val viewBinding: ItemTxQueuedSwapOrderBinding) : + BaseTransactionViewHolder(viewBinding) { + + @OptIn(ExperimentalTime::class) + override fun bind(viewTransfer: TransactionView.TwapOrderTransactionQueued, payloads: List) { + val resources = viewBinding.root.context.resources + val theme = viewBinding.root.context.theme + + with(viewBinding) { + status.setText(viewTransfer.statusText) + status.setTextColor(ResourcesCompat.getColor(resources, viewTransfer.statusColorRes, theme)) + + dateTime.text = viewTransfer.dateTime.elapsedIntervalTo(Date.from(Instant.now())).format(resources) + addressName.text = resources.getString(R.string.tx_list_twap_order) + + confirmationsIcon.setImageDrawable(ResourcesCompat.getDrawable(resources, viewTransfer.confirmationsIcon, theme)) + confirmations.setTextColor(ResourcesCompat.getColor(resources, viewTransfer.confirmationsTextColor, theme)) + confirmations.text = resources.getString(R.string.tx_list_confirmations, viewTransfer.confirmations, viewTransfer.threshold) + + nonce.text = viewTransfer.nonce + + root.setOnClickListener { + navigateToTxDetails(it, viewTransfer.chain, viewTransfer.id) + } + } + } +} + +class TwapOrderViewHolder(private val viewBinding: ItemTxSwapOrderBinding) : + BaseTransactionViewHolder(viewBinding) { + + override fun bind(viewTransfer: TransactionView.TwapOrderTransaction, payloads: List) { + val resources = viewBinding.root.context.resources + val theme = viewBinding.root.context.theme + + with(viewBinding) { + finalStatus.setText(viewTransfer.statusText) + finalStatus.setTextColor(ResourcesCompat.getColor(resources, viewTransfer.statusColorRes, theme)) + dateTime.text = viewTransfer.dateTimeText + + nonce.text = viewTransfer.nonce + addressName.text = resources.getString(R.string.tx_list_twap_order) + + addressLogo.alpha = viewTransfer.alpha + addressName.alpha = viewTransfer.alpha + finalStatus.alpha = OPACITY_FULL + dateTime.alpha = viewTransfer.alpha + nonce.alpha = viewTransfer.alpha + + root.setOnClickListener { + navigateToTxDetails(it, viewTransfer.chain, viewTransfer.id) + } + } + } +} + + private fun Resources.getAction(methodName: String?, actionCount: Int?): String? = if (actionCount != null) { if (actionCount > 0) this.getQuantityString(R.plurals.tx_list_actions, actionCount, actionCount) else methodName diff --git a/app/src/main/java/io/gnosis/safe/ui/transactions/TransactionListViewModel.kt b/app/src/main/java/io/gnosis/safe/ui/transactions/TransactionListViewModel.kt index 16550b7ef..f6193ba95 100644 --- a/app/src/main/java/io/gnosis/safe/ui/transactions/TransactionListViewModel.kt +++ b/app/src/main/java/io/gnosis/safe/ui/transactions/TransactionListViewModel.kt @@ -187,6 +187,8 @@ class TransactionListViewModel toHistoryCreation(chain, txInfo, owner) } is TransactionInfo.SwapOrder -> toSwapOrderTransactionView(chain, txInfo, needsYourConfirmation, isConflict) + is TransactionInfo.SwapTransfer -> toSwapTransferTransactionView(chain, txInfo, needsYourConfirmation, isConflict) + is TransactionInfo.TwapOrder -> toTwapOrderTransactionView(chain, txInfo, needsYourConfirmation, isConflict) TransactionInfo.Unknown -> TransactionView.Unknown } } @@ -421,6 +423,112 @@ class TransactionListViewModel ) } + private fun Transaction.toSwapTransferTransactionView( + chain: Chain, + txInfo: TransactionInfo.SwapTransfer, + needsYourConfirmation: Boolean, + isConflict: Boolean + ): TransactionView = + if (!isCompleted(txStatus)) queuedSwapTransferTransaction(chain, txInfo, needsYourConfirmation, isConflict) + else historicSwapTransferTransaction(chain, txInfo) + + private fun Transaction.historicSwapTransferTransaction( + chain: Chain, + txInfo: TransactionInfo.SwapTransfer + ): TransactionView.SwapTransferTransaction { + + return TransactionView.SwapTransferTransaction( + chain = chain, + id = id, + status = txStatus, + statusText = displayString(txStatus), + statusColorRes = statusTextColor(txStatus), + dateTimeText = timestamp.formatBackendTimeOfDay(), + alpha = alpha(txStatus), + nonce = executionInfo?.nonce?.toString() ?: "", + explorerUrl = txInfo.explorerUrl + ) + } + + private fun Transaction.queuedSwapTransferTransaction( + chain: Chain, + txInfo: TransactionInfo.SwapTransfer, + needsYourConfirmation: Boolean, + isConflict: Boolean + ): TransactionView.SwapTransferTransactionQueued { + + //FIXME this wouldn't make sense for incoming Ethereum TXs + val threshold = executionInfo?.confirmationsRequired ?: -1 + val thresholdMet = checkThreshold(threshold, executionInfo?.confirmationsSubmitted) + + return TransactionView.SwapTransferTransactionQueued( + chain = chain, + id = id, + status = txStatus, + statusText = displayString(txStatus, needsYourConfirmation), + statusColorRes = statusTextColor(txStatus), + dateTime = timestamp, + confirmations = executionInfo?.confirmationsSubmitted ?: 0, + threshold = threshold, + confirmationsTextColor = if (thresholdMet) R.color.success else R.color.icon, + confirmationsIcon = if (thresholdMet) R.drawable.ic_confirmations_green_16dp else R.drawable.ic_confirmations_grey_16dp, + nonce = if (isConflict) "" else executionInfo?.nonce?.toString() ?: "", + explorerUrl = txInfo.explorerUrl + ) + } + + private fun Transaction.toTwapOrderTransactionView( + chain: Chain, + txInfo: TransactionInfo.TwapOrder, + needsYourConfirmation: Boolean, + isConflict: Boolean + ): TransactionView = + if (!isCompleted(txStatus)) queuedTwapOrderTransaction(chain, txInfo, needsYourConfirmation, isConflict) + else historicTwapOrderTransaction(chain, txInfo) + + private fun Transaction.historicTwapOrderTransaction( + chain: Chain, + txInfo: TransactionInfo.TwapOrder + ): TransactionView.TwapOrderTransaction { + + return TransactionView.TwapOrderTransaction( + chain = chain, + id = id, + status = txStatus, + statusText = displayString(txStatus), + statusColorRes = statusTextColor(txStatus), + dateTimeText = timestamp.formatBackendTimeOfDay(), + alpha = alpha(txStatus), + nonce = executionInfo?.nonce?.toString() ?: "" + ) + } + + private fun Transaction.queuedTwapOrderTransaction( + chain: Chain, + txInfo: TransactionInfo.TwapOrder, + needsYourConfirmation: Boolean, + isConflict: Boolean + ): TransactionView.TwapOrderTransactionQueued { + + //FIXME this wouldn't make sense for incoming Ethereum TXs + val threshold = executionInfo?.confirmationsRequired ?: -1 + val thresholdMet = checkThreshold(threshold, executionInfo?.confirmationsSubmitted) + + return TransactionView.TwapOrderTransactionQueued( + chain = chain, + id = id, + status = txStatus, + statusText = displayString(txStatus, needsYourConfirmation), + statusColorRes = statusTextColor(txStatus), + dateTime = timestamp, + confirmations = executionInfo?.confirmationsSubmitted ?: 0, + threshold = threshold, + confirmationsTextColor = if (thresholdMet) R.color.success else R.color.icon, + confirmationsIcon = if (thresholdMet) R.drawable.ic_confirmations_green_16dp else R.drawable.ic_confirmations_grey_16dp, + nonce = if (isConflict) "" else executionInfo?.nonce?.toString() ?: "" + ) + } + private fun Transaction.toRejectionTransactionView( chain: Chain, awaitingYourConfirmation: Boolean, diff --git a/app/src/main/java/io/gnosis/safe/ui/transactions/TransactionView.kt b/app/src/main/java/io/gnosis/safe/ui/transactions/TransactionView.kt index f6cdbd986..fb90a69f3 100644 --- a/app/src/main/java/io/gnosis/safe/ui/transactions/TransactionView.kt +++ b/app/src/main/java/io/gnosis/safe/ui/transactions/TransactionView.kt @@ -142,6 +142,58 @@ sealed class TransactionView( val explorerUrl: String ) : TransactionView(status, id, chain) + data class SwapTransferTransaction( + override val id: String, + override val status: TransactionStatus, + override val chain: Chain, + @StringRes val statusText: Int, + @ColorRes val statusColorRes: Int, + val dateTimeText: String, + val alpha: Float, + val nonce: String, + val explorerUrl: String + ) : TransactionView(status, id, chain) + + data class SwapTransferTransactionQueued( + override val id: String, + override val status: TransactionStatus, + override val chain: Chain, + @StringRes val statusText: Int, + @ColorRes val statusColorRes: Int, + val dateTime: Date, + val confirmations: Int, + val threshold: Int, + @ColorRes val confirmationsTextColor: Int, + @DrawableRes val confirmationsIcon: Int, + val nonce: String, + val explorerUrl: String + ) : TransactionView(status, id, chain) + + data class TwapOrderTransaction( + override val id: String, + override val status: TransactionStatus, + override val chain: Chain, + @StringRes val statusText: Int, + @ColorRes val statusColorRes: Int, + val dateTimeText: String, + val alpha: Float, + val nonce: String, + ) : TransactionView(status, id, chain) + + data class TwapOrderTransactionQueued( + override val id: String, + override val status: TransactionStatus, + override val chain: Chain, + @StringRes val statusText: Int, + @ColorRes val statusColorRes: Int, + val dateTime: Date, + val confirmations: Int, + val threshold: Int, + @ColorRes val confirmationsTextColor: Int, + @DrawableRes val confirmationsIcon: Int, + val nonce: String, + ) : TransactionView(status, id, chain) + data class Creation( override val id: String, override val status: TransactionStatus, diff --git a/app/src/main/java/io/gnosis/safe/ui/transactions/details/TransactionDetailsFragment.kt b/app/src/main/java/io/gnosis/safe/ui/transactions/details/TransactionDetailsFragment.kt index 9a0c7d6e4..94186d825 100644 --- a/app/src/main/java/io/gnosis/safe/ui/transactions/details/TransactionDetailsFragment.kt +++ b/app/src/main/java/io/gnosis/safe/ui/transactions/details/TransactionDetailsFragment.kt @@ -258,7 +258,7 @@ class TransactionDetailsFragment : BaseViewBindingFragment { + val viewStub = binding.stubSettingsChange + if (viewStub.parent != null) { + contentBinding = TxDetailsSettingsChangeBinding.bind(viewStub.inflate()) + } + val txDetailsSettingsChangeBinding = contentBinding as TxDetailsSettingsChangeBinding + with(txDetailsSettingsChangeBinding) { + txAction.visible(true) + txAction.setActionInfoItems( + chain = chain, + showChainPrefix = viewModel.isChainPrefixPrependEnabled(), + copyChainPrefix = viewModel.isChainPrefixCopyEnabled(), + actionInfoItems = listOf(ActionInfoItem.Value( + itemLabel = R.string.tx_status_type_custom , + value = "Swap transfer")) + ) + + txStatus.setStatus( + title = resources.getString(TxType.SWAP_TRANSFER.titleRes), + defaultIconRes = TxType.SWAP_TRANSFER.iconRes, + statusTextRes = getStringResForStatus(txDetails.txStatus, txDetails.canSign && awaitingConfirmations), + statusColorRes = getColorForStatus(txDetails.txStatus) + ) + binding.etherscanDivider.visible(true) + binding.orderLink.visible(true) + binding.orderLink.setOnClickListener { + requireContext().openUrl(txInfo.explorerUrl) + } + } + } + is TransactionInfoViewData.TwapOrder -> { + val viewStub = binding.stubSettingsChange + if (viewStub.parent != null) { + contentBinding = TxDetailsSettingsChangeBinding.bind(viewStub.inflate()) + } + val txDetailsSettingsChangeBinding = contentBinding as TxDetailsSettingsChangeBinding + with(txDetailsSettingsChangeBinding) { + txAction.visible(true) + txAction.setActionInfoItems( + chain = chain, + showChainPrefix = viewModel.isChainPrefixPrependEnabled(), + copyChainPrefix = viewModel.isChainPrefixCopyEnabled(), + actionInfoItems = listOf(ActionInfoItem.Value( + itemLabel = R.string.tx_status_type_custom , + value = "Twap order")) + ) + + txStatus.setStatus( + title = resources.getString(TxType.TWAP_ORDER.titleRes), + defaultIconRes = TxType.TWAP_ORDER.iconRes, + statusTextRes = getStringResForStatus(txDetails.txStatus, txDetails.canSign && awaitingConfirmations), + statusColorRes = getColorForStatus(txDetails.txStatus) + ) + } + } } binding.content.visible(true) diff --git a/app/src/main/java/io/gnosis/safe/ui/transactions/details/view/TxType.kt b/app/src/main/java/io/gnosis/safe/ui/transactions/details/view/TxType.kt index 9e420c104..f1eb8d7ca 100644 --- a/app/src/main/java/io/gnosis/safe/ui/transactions/details/view/TxType.kt +++ b/app/src/main/java/io/gnosis/safe/ui/transactions/details/view/TxType.kt @@ -10,6 +10,8 @@ enum class TxType(@DrawableRes val iconRes: Int, @StringRes val titleRes: Int) { MODIFY_SETTINGS(R.drawable.ic_settings_change_14dp, R.string.tx_status_type_modify_settings), CUSTOM(R.drawable.ic_code_16dp, R.string.tx_status_type_custom), SWAP_ORDER(R.drawable.ic_code_16dp, R.string.tx_status_type_swap_order), + SWAP_TRANSFER(R.drawable.ic_code_16dp, R.string.tx_status_type_swap_transfer), + TWAP_ORDER(R.drawable.ic_code_16dp, R.string.tx_status_type_twap_order), CREATION(R.drawable.ic_settings_change_14dp, R.string.tx_status_type_creation), REJECTION(R.drawable.ic_circle_cross_red_16dp, R.string.tx_status_type_rejection) } diff --git a/app/src/main/java/io/gnosis/safe/ui/transactions/details/viewdata/TransactionDetailsViewData.kt b/app/src/main/java/io/gnosis/safe/ui/transactions/details/viewdata/TransactionDetailsViewData.kt index b177a825e..982b428cd 100644 --- a/app/src/main/java/io/gnosis/safe/ui/transactions/details/viewdata/TransactionDetailsViewData.kt +++ b/app/src/main/java/io/gnosis/safe/ui/transactions/details/viewdata/TransactionDetailsViewData.kt @@ -107,6 +107,17 @@ sealed class TransactionInfoViewData( val explorerUrl: String ) : TransactionInfoViewData(TransactionType.SwapOrder) + @Parcelize + data class SwapTransfer( + val uid: String, + val explorerUrl: String + ) : TransactionInfoViewData(TransactionType.SwapTransfer) + + @Parcelize + data class TwapOrder( + val status: String + ) : TransactionInfoViewData(TransactionType.TwapOrder) + @Parcelize object Unknown : TransactionInfoViewData(TransactionType.Unknown) } @@ -251,6 +262,8 @@ internal fun TransactionInfo.toTransactionInfoViewData( settingsInfo.toSettingsInfoViewData(safes, owners = owners) ) is TransactionInfo.SwapOrder -> TransactionInfoViewData.SwapOrder(uid, explorerUrl) + is TransactionInfo.SwapTransfer -> TransactionInfoViewData.SwapTransfer(uid, explorerUrl) + is TransactionInfo.TwapOrder -> TransactionInfoViewData.TwapOrder(status) is TransactionInfo.Transfer -> { val addressInfoData = if (direction == TransactionDirection.OUTGOING) { diff --git a/app/src/main/java/io/gnosis/safe/utils/TxUtils.kt b/app/src/main/java/io/gnosis/safe/utils/TxUtils.kt index 94a462891..cec5311cc 100644 --- a/app/src/main/java/io/gnosis/safe/utils/TxUtils.kt +++ b/app/src/main/java/io/gnosis/safe/utils/TxUtils.kt @@ -71,6 +71,8 @@ fun TransactionInfoViewData.formattedAmount(chain: Chain, balanceFormatter: Bala is TransactionInfoViewData.Creation -> "0 ${chain.currency.symbol}" is TransactionInfoViewData.Rejection -> "0 ${chain.currency.symbol}" is TransactionInfoViewData.SwapOrder -> "0 ${chain.currency.symbol}" + is TransactionInfoViewData.SwapTransfer -> "0 ${chain.currency.symbol}" + is TransactionInfoViewData.TwapOrder -> "0 ${chain.currency.symbol}" TransactionInfoViewData.Unknown -> "0 ${chain.currency.symbol}" } @@ -89,6 +91,8 @@ fun TransactionInfoViewData.logoUri(chain: Chain): String? = } is TransactionInfoViewData.Custom, is TransactionInfoViewData.SwapOrder, + is TransactionInfoViewData.SwapTransfer, + is TransactionInfoViewData.TwapOrder, is TransactionInfoViewData.SettingsChange, is TransactionInfoViewData.Creation, is TransactionInfoViewData.Rejection, diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c8e067eac..49b71c19a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -377,6 +377,8 @@ Modify settings Contract interaction Swap order + Swap transfer + Twap order Safe Account created On-chain rejection @@ -637,6 +639,8 @@ Unknown Unknown Swap order + Swap transfer + Twap order Contract interaction On-chain rejection These transactions conflict as they use the same nonce. Executing one will automatically replace the other(s). diff --git a/data/src/main/java/io/gnosis/data/adapters/MoshiBuilder.kt b/data/src/main/java/io/gnosis/data/adapters/MoshiBuilder.kt index a1cee2e4d..8938edfaf 100644 --- a/data/src/main/java/io/gnosis/data/adapters/MoshiBuilder.kt +++ b/data/src/main/java/io/gnosis/data/adapters/MoshiBuilder.kt @@ -17,6 +17,8 @@ internal val transactionInfoAdapter = .withSubtype(TransactionInfo.SettingsChange::class.java, "SettingsChange") .withSubtype(TransactionInfo.Custom::class.java, "Custom") .withSubtype(TransactionInfo.SwapOrder::class.java, "SwapOrder") + .withSubtype(TransactionInfo.SwapTransfer::class.java, "SwapTransfer") + .withSubtype(TransactionInfo.TwapOrder::class.java, "TwapOrder") .withSubtype(TransactionInfo.Creation::class.java, "Creation") .withDefaultValue(TransactionInfo.Unknown) diff --git a/data/src/main/java/io/gnosis/data/models/transaction/Transaction.kt b/data/src/main/java/io/gnosis/data/models/transaction/Transaction.kt index 5a9960c08..5a74d64e4 100644 --- a/data/src/main/java/io/gnosis/data/models/transaction/Transaction.kt +++ b/data/src/main/java/io/gnosis/data/models/transaction/Transaction.kt @@ -60,6 +60,12 @@ enum class TransactionType { @Json(name = "SwapOrder") SwapOrder, + @Json(name = "SwapTransfer") + SwapTransfer, + + @Json(name = "TwapOrder") + TwapOrder, + @Json(name = "Unknown") Unknown } diff --git a/data/src/main/java/io/gnosis/data/models/transaction/TransactionInfo.kt b/data/src/main/java/io/gnosis/data/models/transaction/TransactionInfo.kt index 34a55b27e..ecf364315 100644 --- a/data/src/main/java/io/gnosis/data/models/transaction/TransactionInfo.kt +++ b/data/src/main/java/io/gnosis/data/models/transaction/TransactionInfo.kt @@ -43,11 +43,21 @@ sealed class TransactionInfo( @JsonClass(generateAdapter = true) data class SwapOrder( @Json(name = "uid") val uid: String, - @Json(name = "status") val status: String, - @Json(name = "kind") val kind: String, @Json(name = "explorerUrl") val explorerUrl: String ) : TransactionInfo(TransactionType.SwapOrder) + @JsonClass(generateAdapter = true) + data class SwapTransfer( + @Json(name = "uid") val uid: String, + @Json(name = "explorerUrl") val explorerUrl: String + ) : TransactionInfo(TransactionType.SwapTransfer) + + @JsonClass(generateAdapter = true) + data class TwapOrder( + @Json(name = "status") val status: String, + @Json(name = "kind") val kind: String, + ) : TransactionInfo(TransactionType.TwapOrder) + object Unknown : TransactionInfo(TransactionType.Unknown) } diff --git a/data/src/main/java/io/gnosis/data/utils/SafeTxHash.kt b/data/src/main/java/io/gnosis/data/utils/SafeTxHash.kt index 3d1acb25f..0b35cc62c 100644 --- a/data/src/main/java/io/gnosis/data/utils/SafeTxHash.kt +++ b/data/src/main/java/io/gnosis/data/utils/SafeTxHash.kt @@ -44,6 +44,12 @@ fun calculateSafeTxHash( is TransactionInfo.SwapOrder -> { transaction.txData?.to?.value ?: safeAddress } + is TransactionInfo.SwapTransfer -> { + transaction.txData?.to?.value ?: safeAddress + } + is TransactionInfo.TwapOrder -> { + transaction.txData?.to?.value ?: safeAddress + } else -> { throw UnsupportedTransactionType(transaction::javaClass.name) }