Skip to content

Commit d5d394c

Browse files
committed
feat(oc): update protos; handle Denied returned from GetIntentMetadata
improve polling for metadata during scans Signed-off-by: Brandon McAnsh <git@bmcreations.dev>
1 parent e291c73 commit d5d394c

13 files changed

Lines changed: 36 additions & 279 deletions

File tree

apps/flipcash/shared/session/src/main/kotlin/com/flipcash/app/session/internal/RealSessionController.kt

Lines changed: 1 addition & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import com.flipcash.app.core.internal.bill.BillController
1414
import com.flipcash.app.core.internal.errors.showNetworkError
1515
import com.flipcash.app.core.internal.updater.ProfileUpdater
1616
import com.flipcash.app.core.navigation.DeeplinkType
17-
import com.flipcash.app.tokens.TokenUpdater
1817
import com.flipcash.app.featureflags.FeatureFlag
1918
import com.flipcash.app.featureflags.FeatureFlagController
2019
import com.flipcash.app.session.BillDeterminationResult
@@ -29,6 +28,7 @@ import com.flipcash.app.shareable.ShareSheetController
2928
import com.flipcash.app.shareable.Shareable
3029
import com.flipcash.app.shareable.ShareableConfirmationController
3130
import com.flipcash.app.tokens.TokenCoordinator
31+
import com.flipcash.app.tokens.TokenUpdater
3232
import com.flipcash.core.R
3333
import com.flipcash.services.controllers.AccountController
3434
import com.flipcash.services.user.AuthState
@@ -44,9 +44,6 @@ import com.getcode.opencode.model.core.PayloadKind
4444
import com.getcode.opencode.model.financial.LocalFiat
4545
import com.getcode.opencode.model.financial.Token
4646
import com.getcode.opencode.model.financial.sum
47-
import com.getcode.opencode.model.financial.usdf
48-
import com.getcode.opencode.model.transactions.AirdropType
49-
import com.getcode.opencode.utils.nonce
5047
import com.getcode.ui.core.RestrictionType
5148
import com.getcode.util.permissions.PermissionResult
5249
import com.getcode.util.resources.ResourceHelper
@@ -72,7 +69,6 @@ import kotlinx.coroutines.flow.launchIn
7269
import kotlinx.coroutines.flow.map
7370
import kotlinx.coroutines.flow.mapNotNull
7471
import kotlinx.coroutines.flow.onEach
75-
import kotlinx.coroutines.flow.scan
7672
import kotlinx.coroutines.flow.update
7773
import kotlinx.coroutines.launch
7874
import kotlinx.coroutines.suspendCancellableCoroutine
@@ -188,18 +184,6 @@ class RealSessionController @Inject constructor(
188184
.onEach { tokens ->
189185
_state.update { it.copy(tokens = tokens) }
190186
}.launchIn(scope)
191-
192-
state
193-
.map { it.isCameraUp }
194-
.distinctUntilChanged() // Emit only when value changes
195-
.scan(Pair(null as Boolean?, null as Boolean?)) { previousPair, current ->
196-
Pair(previousPair.second, current)
197-
}
198-
.mapNotNull { (previous, current) ->
199-
if (previous == null && current != null) current else null
200-
}
201-
.onEach { checkForAirdrops() }
202-
.launchIn(scope)
203187
}
204188

205189
/**
@@ -274,56 +258,6 @@ class RealSessionController @Inject constructor(
274258
}
275259
}
276260

277-
private fun checkForAirdrops() {
278-
if (userManager.authState.canAccessAuthenticatedApis) {
279-
scope.launch {
280-
userManager.accountCluster?.let {
281-
transactionController.airdrop(
282-
type = AirdropType.WelcomeBonus,
283-
destination = it.authority.keyPair
284-
).onSuccess { amount ->
285-
presentWelcomeBonus(amount)
286-
}
287-
}
288-
}
289-
}
290-
}
291-
292-
private fun presentWelcomeBonus(amount: LocalFiat) {
293-
scope.launch {
294-
val presentWithBill = featureFlagController.get(FeatureFlag.WelcomeBonusBill)
295-
toastController.enqueue(
296-
amount = amount,
297-
isDeposit = true,
298-
initialDelay = if (presentWithBill) ToastController.INITIAL_DELAY else AIRDROP_INITIAL_DELAY
299-
)
300-
301-
if (!presentWithBill) {
302-
// consume the toast immediately
303-
toastController.consumeQueue()
304-
return@launch
305-
}
306-
307-
delay(1.seconds)
308-
val payloadInfo = OpenCodePayload(
309-
kind = PayloadKind.Cash,
310-
value = amount.nativeAmount,
311-
nonce = nonce
312-
)
313-
314-
val bill = Bill.Cash(
315-
token = Token.usdf,
316-
data = payloadInfo.codeData.toList(),
317-
amount = amount,
318-
didReceive = true,
319-
confirmationDelay = 500.milliseconds
320-
)
321-
322-
presentBillToUser(data = payloadInfo.codeData.toList(), bill = bill)
323-
feedCoordinator.fetchSinceLatest()
324-
}
325-
}
326-
327261
private fun checkPendingItemsInFeed() {
328262
if (userManager.authState.canAccessAuthenticatedApis) {
329263
scope.launch {

definitions/opencode/protos/src/main/proto/transaction/v1/transaction_service.proto

Lines changed: 2 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,6 @@ service Transaction {
5151
// CanWithdrawToAccount provides hints to clients for submitting withdraw intents.
5252
// The RPC indicates if a withdrawal is possible, and how it should be performed.
5353
rpc CanWithdrawToAccount(CanWithdrawToAccountRequest) returns (CanWithdrawToAccountResponse);
54-
// Airdrop airdrops core mint tokens to the requesting account
55-
rpc Airdrop(AirdropRequest) returns (AirdropResponse);
5654
// VoidGiftCard voids a gift card account by returning the funds to the funds back
5755
// to the issuer via the auto-return action if it hasn't been claimed or already
5856
// returned.
@@ -160,8 +158,9 @@ message GetIntentMetadataRequest {
160158
message GetIntentMetadataResponse {
161159
Result result = 1;
162160
enum Result {
163-
OK = 0;
161+
OK = 0;
164162
NOT_FOUND = 1;
163+
DENIED = 2;
165164
}
166165
Metadata metadata = 2;
167166
}
@@ -225,28 +224,6 @@ message CanWithdrawToAccountResponse {
225224
// Note: The fee is always paid in the target mint.
226225
ExchangeDataWithoutRate fee_amount = 4;
227226
}
228-
message AirdropRequest {
229-
// The type of airdrop to claim
230-
AirdropType airdrop_type = 1 ;
231-
// The owner account to airdrop core mint tokens to
232-
common.v1.SolanaAccountId owner = 2;
233-
// The signature is of serialize(AirdropRequest) without this field set
234-
// using the private key of the owner account. This provides an authentication
235-
// mechanism to the RPC.
236-
common.v1.Signature signature = 3;
237-
}
238-
message AirdropResponse {
239-
Result result = 1;
240-
enum Result {
241-
OK = 0;
242-
// Airdrops are unavailable
243-
UNAVAILABLE = 1;
244-
// The airdrop has already been claimed by the owner
245-
ALREADY_CLAIMED = 2;
246-
}
247-
// Exchange data for the amount of core mint tokens airdropped when successful
248-
ExchangeData exchange_data = 2;
249-
}
250227
message VoidGiftCardRequest {
251228
// The owner account that issued the gift card account
252229
common.v1.SolanaAccountId owner = 1;
@@ -819,13 +796,6 @@ message SwapMetadata {
819796
CANCELLED = 8; // The swap transaction is cancelled. Funds have been deposited back into the VM
820797
}
821798
}
822-
enum AirdropType {
823-
UNKNOWN = 0;
824-
// Reward for onboarding another user
825-
ONBOARDING_BONUS = 1;
826-
// Airdrop for getting a user started with first crypto balance
827-
WELCOME_BONUS = 2;
828-
}
829799
enum FundingSource {
830800
FUNDING_SOURCE_UNKNOWN = 0;
831801
FUNDING_SOURCE_SUBMIT_INTENT = 1;

services/opencode/src/main/kotlin/com/getcode/opencode/controllers/TransactionController.kt

Lines changed: 8 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import com.getcode.opencode.internal.network.api.intents.IntentWithdraw
1111
import com.getcode.opencode.internal.solana.model.SwapId
1212
import com.getcode.opencode.model.accounts.AccountCluster
1313
import com.getcode.opencode.model.accounts.GiftCardAccount
14+
import com.getcode.opencode.model.core.errors.GetIntentMetadataError
1415
import com.getcode.opencode.model.core.errors.SwapError
1516
import com.getcode.opencode.model.financial.Distribution
1617
import com.getcode.opencode.model.financial.Fee
@@ -19,7 +20,6 @@ import com.getcode.opencode.model.financial.Fiat
1920
import com.getcode.opencode.model.financial.Limits
2021
import com.getcode.opencode.model.financial.LocalFiat
2122
import com.getcode.opencode.model.financial.Token
22-
import com.getcode.opencode.model.transactions.AirdropType
2323
import com.getcode.opencode.model.transactions.ExchangeData
2424
import com.getcode.opencode.model.transactions.SwapFundingSource
2525
import com.getcode.opencode.model.transactions.SwapMetadata
@@ -36,6 +36,7 @@ import com.getcode.solana.keys.PublicKey
3636
import com.getcode.utils.TraceType
3737
import com.getcode.utils.base64
3838
import com.getcode.utils.trace
39+
import com.getcode.vendor.Base58
3940
import com.hoc081098.channeleventbus.ChannelEventBus
4041
import kotlinx.coroutines.CoroutineScope
4142
import kotlinx.coroutines.Dispatchers
@@ -50,7 +51,6 @@ import kotlinx.coroutines.flow.map
5051
import kotlinx.coroutines.flow.mapNotNull
5152
import kotlinx.coroutines.flow.onEach
5253
import kotlinx.coroutines.flow.takeWhile
53-
import com.getcode.vendor.Base58
5454
import java.util.concurrent.atomic.AtomicBoolean
5555
import java.util.concurrent.atomic.AtomicInteger
5656
import javax.inject.Inject
@@ -97,23 +97,6 @@ class TransactionController @Inject constructor(
9797
}
9898
}
9999

100-
suspend fun airdrop(
101-
destination: KeyPair,
102-
type: AirdropType
103-
): Result<LocalFiat> {
104-
return repository.airdrop(
105-
type = type,
106-
destination = destination
107-
).onSuccess {
108-
trace(
109-
tag = "Transactions",
110-
message = "Airdrop was successful.",
111-
type = TraceType.Process
112-
)
113-
eventBus.send(Events.FetchBalance())
114-
}.map { LocalFiat(it) }
115-
}
116-
117100
suspend fun transfer(
118101
amount: LocalFiat,
119102
mint: Mint,
@@ -350,7 +333,6 @@ class TransactionController @Inject constructor(
350333
maxAttempts: Int = 10,
351334
debugLogs: Boolean = false,
352335
): Result<T> {
353-
val stopped = AtomicBoolean()
354336
val attemptCount = AtomicInteger()
355337

356338
if (debugLogs) {
@@ -362,7 +344,7 @@ class TransactionController @Inject constructor(
362344
}
363345

364346
return flowInterval({ 50L * (attemptCount.get() / 10) })
365-
.takeWhile { !stopped.get() && attemptCount.get() < maxAttempts }
347+
.takeWhile { attemptCount.get() < maxAttempts }
366348
.map { attemptCount.incrementAndGet() }
367349
.onEach {
368350
if (debugLogs) {
@@ -373,16 +355,7 @@ class TransactionController @Inject constructor(
373355
)
374356
}
375357
}
376-
.map {
377-
try {
378-
val result = repository.getIntentMetadata(intentId, owner)
379-
Result.success(
380-
result.getOrNull() ?: throw IllegalStateException("No metadata received")
381-
)
382-
} catch (e: Exception) {
383-
Result.failure(e)
384-
}
385-
}
358+
.map { repository.getIntentMetadata(intentId, owner) }
386359
.onEach {
387360
if (debugLogs) {
388361
trace(
@@ -392,7 +365,6 @@ class TransactionController @Inject constructor(
392365
)
393366
}
394367
}
395-
.filter { !stopped.get() }
396368
.mapNotNull { result ->
397369
result.fold(
398370
onSuccess = { metadata ->
@@ -405,7 +377,10 @@ class TransactionController @Inject constructor(
405377
}
406378
metadata
407379
},
408-
onFailure = { null }
380+
onFailure = { error ->
381+
if (error is GetIntentMetadataError.Denied) throw error
382+
null
383+
}
409384
)
410385
}.mapNotNull { it as? T }
411386
.map { Result.success(it) }

services/opencode/src/main/kotlin/com/getcode/opencode/events/Events.kt

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,6 @@ sealed interface Events {
1515
companion object Key : ChannelEventKey<OnLoggedIn>(OnLoggedIn::class)
1616
}
1717

18-
data class RequestWelcomeBonus(internal val owner: AccountCluster): ChannelEvent<RequestWelcomeBonus>,
19-
Events {
20-
override val key: ChannelEvent.Key<RequestWelcomeBonus> = Key
21-
companion object Key : ChannelEventKey<RequestWelcomeBonus>(RequestWelcomeBonus::class)
22-
}
23-
2418
data class UpdateLimits(internal val owner: AccountCluster, internal val force: Boolean = false): ChannelEvent<UpdateLimits>,
2519
Events {
2620
override val key: ChannelEvent.Key<UpdateLimits> = Key

services/opencode/src/main/kotlin/com/getcode/opencode/internal/domain/repositories/InternalEventRepository.kt

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package com.getcode.opencode.internal.domain.repositories
33
import com.getcode.opencode.controllers.AccountController
44
import com.getcode.opencode.controllers.TransactionController
55
import com.getcode.opencode.events.Events
6-
import com.getcode.opencode.model.transactions.AirdropType
76
import com.getcode.opencode.providers.SessionListener
87
import com.getcode.opencode.repositories.EventRepository
98
import com.hoc081098.channeleventbus.ChannelEvent
@@ -45,15 +44,6 @@ internal class InternalEventRepository @Inject constructor(
4544
}
4645
}
4746

48-
eventBus.handle(Events.RequestWelcomeBonus) {
49-
scope.launch {
50-
transactionController.airdrop(
51-
type = AirdropType.WelcomeBonus,
52-
destination = it.owner.authority.keyPair
53-
)
54-
}
55-
}
56-
5747
eventBus.handle(Events.UpdateLimits) {
5848
scope.launch {
5949
transactionController.updateLimits(

services/opencode/src/main/kotlin/com/getcode/opencode/internal/domain/repositories/InternalTransactionRepository.kt

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ import com.getcode.opencode.model.accounts.AccountCluster
88
import com.getcode.opencode.model.financial.Limits
99
import com.getcode.opencode.model.financial.LocalFiat
1010
import com.getcode.opencode.model.financial.Token
11-
import com.getcode.opencode.model.transactions.AirdropType
12-
import com.getcode.opencode.model.transactions.ExchangeData
1311
import com.getcode.opencode.model.transactions.SwapFundingSource
1412
import com.getcode.opencode.model.transactions.SwapRequest
1513
import com.getcode.opencode.model.transactions.TransactionMetadata
@@ -46,11 +44,6 @@ internal class InternalTransactionRepository @Inject constructor(
4644
mint: Mint,
4745
): Result<WithdrawalAvailability> = service.withdrawalAvailability(destination, mint)
4846

49-
override suspend fun airdrop(
50-
type: AirdropType,
51-
destination: Ed25519.KeyPair
52-
): Result<ExchangeData.WithRate> = service.airdrop(type, destination)
53-
5447
override suspend fun voidGiftCard(
5548
owner: Ed25519.KeyPair,
5649
giftCardVault: PublicKey

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

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ package com.getcode.opencode.internal.network.api
22

33
import com.codeinc.opencode.gen.transaction.v1.TransactionGrpcKt
44
import com.codeinc.opencode.gen.transaction.v1.TransactionService
5-
import com.codeinc.opencode.gen.transaction.v1.TransactionService.AirdropRequest
6-
import com.codeinc.opencode.gen.transaction.v1.TransactionService.AirdropResponse
75
import com.codeinc.opencode.gen.transaction.v1.TransactionService.CanWithdrawToAccountRequest
86
import com.codeinc.opencode.gen.transaction.v1.TransactionService.CanWithdrawToAccountResponse
97
import com.codeinc.opencode.gen.transaction.v1.TransactionService.GetIntentMetadataRequest
@@ -25,7 +23,6 @@ import com.getcode.opencode.internal.network.extensions.asSolanaAccountId
2523
import com.getcode.opencode.internal.network.extensions.asSwapId
2624
import com.getcode.opencode.internal.network.extensions.sign
2725
import com.getcode.opencode.internal.solana.model.SwapId
28-
import com.getcode.opencode.model.transactions.AirdropType
2926
import com.getcode.solana.keys.Mint
3027
import com.getcode.solana.keys.PublicKey
3128
import io.grpc.ManagedChannel
@@ -151,27 +148,6 @@ class TransactionApi @Inject constructor(
151148
}
152149
}
153150

154-
/**
155-
* Airdrops Kin to the requesting account
156-
*
157-
* @param type The type of airdrop to claim
158-
* @param destination The owner account to airdrop Kin to
159-
*/
160-
suspend fun airdrop(
161-
type: AirdropType,
162-
destination: KeyPair,
163-
): AirdropResponse {
164-
val request = AirdropRequest.newBuilder()
165-
.setAirdropType(TransactionService.AirdropType.forNumber(type.ordinal))
166-
.setOwner(destination.asSolanaAccountId())
167-
.apply { setSignature(sign(destination)) }
168-
.build()
169-
170-
return withContext(Dispatchers.IO) {
171-
api.airdrop(request)
172-
}
173-
}
174-
175151
/**
176152
* Voids a gift card account by returning the funds to the funds back
177153
* to the issuer via the auto-return action if it hasn't been claimed or already

0 commit comments

Comments
 (0)