Skip to content

Commit fae7743

Browse files
committed
fix(flipcash): correct intent for distribution
Signed-off-by: Brandon McAnsh <git@bmcreations.dev>
1 parent 3915560 commit fae7743

11 files changed

Lines changed: 99 additions & 23 deletions

File tree

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
11
package com.flipcash.app.core.pools
22

3+
import kotlinx.serialization.Serializable
4+
5+
@Serializable
36
sealed interface PoolResolution {
7+
@Serializable
48
data object NotSet: PoolResolution
59

610
sealed interface DecisionMade
711
sealed interface HasWinner: DecisionMade
12+
13+
@Serializable
814
data class BooleanResolution(val value: Boolean): PoolResolution, HasWinner
15+
@Serializable
916
data object Refund: PoolResolution, DecisionMade
1017
}

apps/flipcash/core/src/main/res/values/strings.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,13 @@
226226
<string name="error_title_resolvePoolFailed">Something Went Wrong</string>
227227
<string name="error_description_resolvePoolFailed">We were unable to resolve your pool. Please try again</string>
228228

229+
<string name="error_title_resolvePoolDistributionsFailed">Pool Distributions Failed</string>
230+
<string name="error_description_resolvePoolDistributionsFailed">
231+
The distributions for this pool could not be completed. Please try again
232+
%1$s
233+
</string>
234+
235+
229236
<string name="action_swipeToBuyIn">Swipe to Buy In</string>
230237

231238
<string name="title_open">Open</string>

apps/flipcash/features/pools/src/main/kotlin/com/flipcash/app/pools/internal/betting/PoolBettingScreenContent.kt

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,15 @@ private fun PoolBettingScreenContent(
4949
}
5050
},
5151
bottomBar = {
52-
if (state.isLoaded && state.isDistributed != true && !state.isResolved) {
53-
BettingBottomBar(state)
52+
if (state.isLoaded) {
53+
when {
54+
!state.isResolved -> {
55+
BettingBottomBar(state)
56+
}
57+
state.isDistributed == false -> {
58+
BettingBottomBar(state)
59+
}
60+
}
5461
}
5562
}
5663
) { innerPadding ->

apps/flipcash/shared/payments/src/main/kotlin/com/flipcash/app/payments/internal/InternalPaymentController.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ internal class InternalPaymentController(
220220
}
221221
is PaymentError.NoOwnerForDistribution -> presentPaymentFailedError()
222222
is PaymentError.NoPoolBalance -> presentPaymentFailedError()
223+
is PaymentError.PoolDistributionFailed -> presentPaymentFailedError()
223224
}
224225
}
225226

@@ -260,4 +261,12 @@ sealed interface PaymentError {
260261
PaymentError, Throwable(message)
261262
data class NoOwnerForDistribution(override val message: String? = "No owner for distribution") : PaymentError, Throwable(message)
262263
data class NoPoolBalance(override val message: String? = "No pool balance") : PaymentError, Throwable(message)
264+
265+
data class PoolDistributionFailed(
266+
override val message: String = "Failed to distribute funds",
267+
override val cause: Throwable,
268+
): PaymentError, Throwable(
269+
message = message,
270+
cause = cause,
271+
)
263272
}

apps/flipcash/shared/payments/src/main/kotlin/com/flipcash/app/payments/internal/InternalPoolBidDelegate.kt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import com.getcode.opencode.model.financial.Fiat
1313
import com.getcode.opencode.model.financial.LocalFiat
1414
import com.getcode.solana.keys.PublicKey
1515
import com.getcode.utils.getPublicKeyBase58
16+
import com.getcode.utils.trace
1617
import javax.inject.Inject
1718

1819
internal class InternalPoolBidDelegate @Inject constructor(
@@ -56,6 +57,19 @@ internal class InternalPoolBidDelegate @Inject constructor(
5657
balanceController.subtract(localizedAmount)
5758
onSuccess(it)
5859
}.onFailure {
60+
trace(
61+
tag = "Pool::bid",
62+
message = "Failed to pay for bid",
63+
error = it,
64+
metadata = {
65+
"pool ID" to pool.id
66+
"pool derivation index" to pool.derivationIndex
67+
"user balance" to balance.formatted()
68+
"bid ID" to bidId
69+
"bid amount" to amount.formatted()
70+
"pool rendezvous" to rendezvous.getPublicKeyBase58()
71+
}
72+
)
5973
onError(it)
6074
}
6175
}

apps/flipcash/shared/payments/src/main/kotlin/com/flipcash/app/payments/internal/InternalPoolResolveDelegate.kt

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,9 @@ import com.flipcash.app.activityfeed.ActivityFeedCoordinator
44
import com.flipcash.app.core.pools.Pool
55
import com.flipcash.app.core.pools.PoolBet
66
import com.flipcash.app.core.pools.PoolBetOutcome
7-
import com.flipcash.app.core.pools.PoolBetSummary
87
import com.flipcash.app.core.pools.PoolResolution
98
import com.flipcash.app.core.pools.PoolWithBets
10-
import com.flipcash.app.payments.delegates.DelegateEvent
119
import com.flipcash.app.payments.delegates.PoolResolveDelegate
12-
import com.flipcash.services.models.NetworkPoolBetOutcome
13-
import com.flipcash.services.models.NetworkPoolResolution
1410
import com.flipcash.services.user.UserManager
1511
import com.getcode.ed25519.Ed25519
1612
import com.getcode.opencode.controllers.AccountController
@@ -19,13 +15,14 @@ import com.getcode.opencode.controllers.TransactionController
1915
import com.getcode.opencode.exchange.Exchange
2016
import com.getcode.opencode.model.accounts.AccountCluster
2117
import com.getcode.opencode.model.accounts.AccountFilter
22-
import com.getcode.opencode.model.accounts.AccountType
2318
import com.getcode.opencode.model.core.ID
2419
import com.getcode.opencode.model.core.RandomId
2520
import com.getcode.opencode.model.financial.Distribution
2621
import com.getcode.opencode.model.financial.Fiat
2722
import com.getcode.opencode.model.financial.LocalFiat
28-
import com.getcode.opencode.model.financial.toFiat
23+
import com.getcode.solana.keys.base58
24+
import com.getcode.utils.getPublicKeyBase58
25+
import com.getcode.utils.trace
2926
import javax.inject.Inject
3027

3128
class InternalPoolResolveDelegate @Inject constructor(
@@ -89,7 +86,36 @@ class InternalPoolResolveDelegate @Inject constructor(
8986
activityFeedCoordinator.fetchSinceLatest()
9087
onSuccess(it)
9188
}.onFailure {
92-
onError(it)
89+
val error = PaymentError.PoolDistributionFailed(cause = it)
90+
val metadata = buildMap {
91+
put("pool name", pool.name)
92+
put("pool resolution", resolution)
93+
put("pool account authority", poolAccount.cluster.authorityPublicKey.base58())
94+
put("pool funding destination", pool.fundingDestination.base58())
95+
put("pool account vault", poolAccount.cluster.vaultPublicKey.base58())
96+
put("pool derivation index", pool.derivationIndex)
97+
put("winning bet count", distributions.count())
98+
put("winning bet amount", distributions.firstOrNull()?.amount?.formatted())
99+
}
100+
trace(
101+
tag = "Pool::resolve",
102+
message = "Failed to distribute funds",
103+
error = error,
104+
metadata = {
105+
metadata.forEach { (k, v) ->
106+
k to v
107+
}
108+
}
109+
)
110+
111+
onError(
112+
error.copy(
113+
message = """
114+
---
115+
DEBUG: ${metadata.entries.joinToString()}
116+
""".trimIndent()
117+
)
118+
)
93119
}
94120
}
95121

@@ -111,7 +137,7 @@ class InternalPoolResolveDelegate @Inject constructor(
111137
usdc = pool.buyIn.convertingTo(rate),
112138
converted = pool.buyIn,
113139
)
114-
val distros = paidBets.map {
140+
val distros = paidBets.map {
115141
Distribution(
116142
destination = it.payoutDestination,
117143
amount = localizedAmount.usdc,
@@ -158,7 +184,8 @@ class InternalPoolResolveDelegate @Inject constructor(
158184
}
159185

160186
return DistributionList(
161-
balanceIncrement = distros.firstOrNull()?.amount?.let { LocalFiat(usdc = it) }.takeIf { paidBets.any { it.userId == userManager.accountId } },
187+
balanceIncrement = distros.firstOrNull()?.amount?.let { LocalFiat(usdc = it) }
188+
.takeIf { paidBets.any { it.userId == userManager.accountId } },
162189
distributions = distros,
163190
)
164191
}

services/flipcash/src/main/kotlin/com/flipcash/services/models/PoolMetadata.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import com.getcode.opencode.model.financial.Fiat
66
import com.getcode.solana.keys.PublicKey
77
import kotlinx.datetime.Clock
88
import kotlinx.datetime.Instant
9+
import kotlinx.serialization.Serializable
910
import javax.annotation.concurrent.Immutable
1011

1112
/**
@@ -72,12 +73,16 @@ data class NetworkPool(
7273
val userSummary: NetworkPoolUserSummary?,
7374
)
7475

76+
@Serializable
7577
sealed interface NetworkPoolResolution {
78+
@Serializable
7679
data object NotSet : NetworkPoolResolution
7780

81+
@Serializable
7882
@Immutable
7983
data object Refund : NetworkPoolResolution
8084

85+
@Serializable
8186
@Immutable
8287
data class BooleanResolution(val value: Boolean) : NetworkPoolResolution
8388
}

services/opencode/src/main/kotlin/com/getcode/opencode/internal/network/api/intents/IntentDistribution.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ internal class IntentDistribution(
4343
distributions.dropLast(1).forEach { dist ->
4444
add(
4545
ActionPublicTransfer.newInstance(
46-
owner = owner.authority.keyPair,
46+
owner = source.authority.keyPair,
4747
source = source.vaultPublicKey,
4848
amount = dist.amount,
4949
destination = dist.destination
@@ -54,7 +54,8 @@ internal class IntentDistribution(
5454
add(
5555
ActionPublicWithdraw.newInstance(
5656
amount = dist.amount,
57-
sourceCluster = source,
57+
owner = source,
58+
source = source,
5859
destination = dist.destination,
5960
canAutoReturn = false
6061
)

services/opencode/src/main/kotlin/com/getcode/opencode/internal/network/api/intents/IntentRemoteReceive.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@ package com.getcode.opencode.internal.network.api.intents
22

33
import com.codeinc.opencode.gen.transaction.v2.TransactionService
44
import com.getcode.opencode.internal.network.api.intents.actions.ActionPublicWithdraw
5-
import com.getcode.opencode.internal.network.extensions.asExchangeData
65
import com.getcode.opencode.internal.network.extensions.asProtobufMetadata
7-
import com.getcode.opencode.internal.network.extensions.asSolanaAccountId
86
import com.getcode.opencode.model.accounts.AccountCluster
97
import com.getcode.opencode.model.accounts.GiftCardAccount
108
import com.getcode.opencode.model.financial.LocalFiat
@@ -33,7 +31,8 @@ internal class IntentRemoteReceive(
3331
// 1. Move all funds from the gift card to the primary account
3432
val withdrawFromGiftCard = ActionPublicWithdraw.newInstance(
3533
amount = amount.usdc,
36-
sourceCluster = giftCard.cluster,
34+
owner = giftCard.cluster,
35+
source = giftCard.cluster,
3736
destination = owner.vaultPublicKey,
3837
canAutoReturn = false,
3938
)

services/opencode/src/main/kotlin/com/getcode/opencode/internal/network/api/intents/IntentRemoteSend.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@ import com.codeinc.opencode.gen.transaction.v2.TransactionService
44
import com.getcode.opencode.internal.network.api.intents.actions.ActionOpenAccount
55
import com.getcode.opencode.internal.network.api.intents.actions.ActionPublicTransfer
66
import com.getcode.opencode.internal.network.api.intents.actions.ActionPublicWithdraw
7-
import com.getcode.opencode.internal.network.extensions.asExchangeData
87
import com.getcode.opencode.internal.network.extensions.asProtobufMetadata
9-
import com.getcode.opencode.internal.network.extensions.asSolanaAccountId
108
import com.getcode.opencode.model.accounts.AccountCluster
119
import com.getcode.opencode.model.accounts.GiftCardAccount
1210
import com.getcode.opencode.model.financial.LocalFiat
@@ -45,7 +43,8 @@ internal class IntentRemoteSend(
4543
// 3. Allow auto-returning back to the primary if not collected
4644
val withdrawToDestination = ActionPublicWithdraw.newInstance(
4745
amount = amount.usdc,
48-
sourceCluster = giftCard.cluster,
46+
owner = giftCard.cluster,
47+
source = giftCard.cluster,
4948
destination = sourceCluster.vaultPublicKey,
5049
canAutoReturn = true
5150
)

0 commit comments

Comments
 (0)