Skip to content

Commit 83dc183

Browse files
committed
feat(phone): update protos and scaffold LinkForPayment RPC
Update flipcash protobuf definitions and add service layer stubs for the new LinkForPayment RPC which links a verified phone number for payment. Signed-off-by: Brandon McAnsh <git@bmcreations.dev>
1 parent e635627 commit 83dc183

7 files changed

Lines changed: 88 additions & 1 deletion

File tree

definitions/flipcash/protos/src/main/proto/phone/v1/phone_verification_service.proto

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ service PhoneVerification {
2222

2323
// Unlink removes the link of a phone number from a user.
2424
rpc Unlink(UnlinkRequest) returns (UnlinkResponse);
25+
26+
// LinkForPayment links the verified phone number for the requesting user for payment.
27+
rpc LinkForPayment(LinkForPaymentRequest) returns (LinkForPaymentResponse);
2528
}
2629

2730
message SendVerificationCodeRequest {
@@ -94,3 +97,20 @@ message UnlinkResponse {
9497
DENIED = 1;
9598
}
9699
}
100+
101+
102+
message LinkForPaymentRequest {
103+
// The phone number to link for payment
104+
PhoneNumber phone_number = 1 [(validate.rules).message.required = true];
105+
106+
common.v1.Auth auth = 2 [(validate.rules).message.required = true];
107+
}
108+
109+
message LinkForPaymentResponse {
110+
Result result = 1;
111+
enum Result {
112+
OK = 0;
113+
DENIED = 1;
114+
NOT_ASSOCIATED = 2;
115+
}
116+
}

services/flipcash/src/main/kotlin/com/flipcash/services/controllers/ContactVerificationController.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,11 @@ class ContactVerificationController @Inject constructor(
3636
userManager.set(updated)
3737
}
3838
}
39+
40+
suspend fun linkForPayment(method: ContactMethod.Phone): Result<Unit> {
41+
val owner = userManager.accountCluster?.authority?.keyPair
42+
?: return Result.failure(Throwable("No account cluster in UserManager"))
43+
44+
return repository.linkForPayment(method, owner)
45+
}
3946
}

services/flipcash/src/main/kotlin/com/flipcash/services/internal/network/api/PhoneVerificationApi.kt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,20 @@ internal class PhoneVerificationApi @Inject constructor(
8787
api.unlink(request)
8888
}
8989
}
90+
91+
suspend fun linkForPayment(
92+
request: ContactMethod.Phone,
93+
owner: Ed25519.KeyPair
94+
): PhoneVerificationService.LinkForPaymentResponse {
95+
val request = PhoneVerificationService.LinkForPaymentRequest.newBuilder()
96+
.setPhoneNumber(Model.PhoneNumber.newBuilder().setValue(request.phoneNumber).build())
97+
.apply { setAuth(authenticate(owner)) }
98+
.build()
99+
100+
request.validate().orThrow()
101+
102+
return withContext(Dispatchers.IO) {
103+
api.linkForPayment(request)
104+
}
105+
}
90106
}

services/flipcash/src/main/kotlin/com/flipcash/services/internal/network/services/PhoneVerificationService.kt

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package com.flipcash.services.internal.network.services
33
import com.flipcash.services.internal.network.api.PhoneVerificationApi
44
import com.getcode.opencode.utils.toValidationOrElse
55
import com.flipcash.services.models.ContactMethod
6+
import com.flipcash.services.models.LinkForPaymentError
67
import com.flipcash.services.models.PhoneVerificationError
78
import com.getcode.ed25519.Ed25519
89
import com.getcode.opencode.internal.network.extensions.foldWithSuppression
@@ -111,4 +112,32 @@ internal class PhoneVerificationService @Inject constructor(
111112
}
112113
)
113114
}
115+
116+
suspend fun linkForPayment(
117+
request: ContactMethod.Phone,
118+
owner: Ed25519.KeyPair
119+
): Result<Unit> {
120+
return runCatching {
121+
api.linkForPayment(request, owner)
122+
}.foldWithSuppression(
123+
onSuccess = { response ->
124+
when (response.result) {
125+
RpcPhoneService.LinkForPaymentResponse.Result.OK -> Result.success(Unit)
126+
RpcPhoneService.LinkForPaymentResponse.Result.DENIED -> {
127+
Result.failure(LinkForPaymentError.Denied())
128+
}
129+
RpcPhoneService.LinkForPaymentResponse.Result.NOT_ASSOCIATED -> {
130+
Result.failure(LinkForPaymentError.NotAssociated())
131+
}
132+
RpcPhoneService.LinkForPaymentResponse.Result.UNRECOGNIZED -> {
133+
Result.failure(LinkForPaymentError.Unrecognized())
134+
}
135+
else -> Result.failure(LinkForPaymentError.Other())
136+
}
137+
},
138+
onFailure = { cause ->
139+
Result.failure(cause.toValidationOrElse { LinkForPaymentError.Other(it) })
140+
}
141+
)
142+
}
114143
}

services/flipcash/src/main/kotlin/com/flipcash/services/internal/repositories/InternalContactVerificationRepository.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,9 @@ internal class InternalContactVerificationRepository(
3838
is ContactMethod.Phone -> phoneService.unlink(method, owner)
3939
}.onFailure { ErrorUtils.handleError(it) }
4040
}
41+
42+
override suspend fun linkForPayment(method: ContactMethod.Phone, owner: Ed25519.KeyPair): Result<Unit> {
43+
return phoneService.linkForPayment(method, owner)
44+
.onFailure { ErrorUtils.handleError(it) }
45+
}
4146
}

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,16 @@ sealed class PhoneVerificationError(
175175
data class Other(override val cause: Throwable? = null) : PhoneVerificationError(message = cause?.message, cause = cause), NotifiableError
176176
}
177177

178+
sealed class LinkForPaymentError(
179+
override val message: String? = null,
180+
override val cause: Throwable? = null
181+
): CodeServerError(message, cause) {
182+
class Denied: LinkForPaymentError("Denied")
183+
class NotAssociated: LinkForPaymentError("Not associated")
184+
class Unrecognized : LinkForPaymentError("Unrecognized"), NotifiableError
185+
data class Other(override val cause: Throwable? = null) : LinkForPaymentError(message = cause?.message, cause = cause), NotifiableError
186+
}
187+
178188
sealed class GetUserProfileError(
179189
override val message: String? = null,
180190
override val cause: Throwable? = null

services/flipcash/src/main/kotlin/com/flipcash/services/repository/ContactVerificationRepository.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ interface ContactVerificationRepository {
77
suspend fun sendVerificationCode(method: ContactMethod, owner: Ed25519.KeyPair): Result<Unit>
88
suspend fun checkVerificationCode(method: ContactMethod, code: String, owner: Ed25519.KeyPair): Result<Unit>
99
suspend fun unlink(method: ContactMethod, owner: Ed25519.KeyPair): Result<Unit>
10-
10+
suspend fun linkForPayment(method: ContactMethod.Phone, owner: Ed25519.KeyPair): Result<Unit>
1111
}

0 commit comments

Comments
 (0)