Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import com.getcode.opencode.internal.solana.model.SwapId
import com.getcode.opencode.model.core.errors.CheckTokenAvailabilityError
import com.getcode.opencode.model.core.errors.GetMintsError
import com.getcode.opencode.model.core.errors.LaunchTokenError
import com.getcode.opencode.model.core.errors.ValidationException
import com.getcode.opencode.model.financial.MintMetadata
import com.getcode.opencode.model.financial.Token
import com.getcode.opencode.model.financial.TokenCreateRequest
Expand Down Expand Up @@ -280,6 +281,7 @@ internal class CurrencyCreatorViewModel @Inject constructor(
onError = { cause ->
dispatchEvent(Event.UpdateProcessingState())
when (cause) {
is ValidationException,
is TextModerationError.Flagged,
is TextModerationError.Denied -> {
BottomBarManager.showAlert(
Expand Down Expand Up @@ -330,6 +332,7 @@ internal class CurrencyCreatorViewModel @Inject constructor(
dispatchEvent(Event.UpdateProcessingState())
stateFlow.value.icon.dataOrNull?.let { contentReader.removeFromCache(it) }
when (cause) {
is ValidationException,
is ImageModerationError.Flagged,
is ImageModerationError.Denied -> {
BottomBarManager.showAlert(
Expand Down Expand Up @@ -379,6 +382,7 @@ internal class CurrencyCreatorViewModel @Inject constructor(
onError = { cause ->
dispatchEvent(Event.UpdateProcessingState())
when (cause) {
is ValidationException,
is TextModerationError.Flagged,
is TextModerationError.Denied -> {
BottomBarManager.showAlert(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ class SwapViewModelErrorTest {
fun `buy failure shows buySellFailed error`() = runTest(mainCoroutineRule.dispatcher) {
dispatchers = TestDispatchers(testScheduler)
transactionController.stub {
onBlocking { buy(any(), any(), anyOrNull(), any(), any(), anyOrNull()) } doReturn
onBlocking { buy(any(), any(), anyOrNull(), anyOrNull(), any(), anyOrNull(), anyOrNull()) } doReturn
Result.failure(RuntimeException("buy failed"))
}

Expand Down
8 changes: 7 additions & 1 deletion definitions/flipcash/models/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import dev.bmcreations.protovalidate.gradle.ProtoVariant
import org.apache.tools.ant.taskdefs.condition.Os

plugins {
alias(libs.plugins.flipcash.android.library)
id("com.google.protobuf")
alias(libs.plugins.protobuf)
alias(libs.plugins.protobuf.validate)
}

val archSuffix = if (Os.isFamily(Os.FAMILY_MAC)) ":osx-x86_64" else ""
Expand Down Expand Up @@ -64,3 +66,7 @@ protobuf {
}
}
}

protovalidate {
variant.set(ProtoVariant.PGV)
}
Original file line number Diff line number Diff line change
@@ -1,30 +1,39 @@
syntax = "proto3";

package flipcash.account.v1;

option go_package = "github.com/code-payments/flipcash2-protobuf-api/generated/go/account/v1;acountpb";
option java_package = "com.codeinc.flipcash.gen.account.v1";
option objc_class_prefix = "FPBAccountV1";

import "common/v1/common.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";
import "validate/validate.proto";

service Account {
// Register registers a new user, bound to the provided PublicKey.
// If the PublicKey is already in use, the previous user account is returned.
rpc Register(RegisterRequest) returns (RegisterResponse);

// Login retrieves the UserId (and in the future, potentially other information)
// required for 'recovering' an account.
rpc Login(LoginRequest) returns (LoginResponse);

// GetUserFlags gets user-specific flags.
rpc GetUserFlags(GetUserFlagsRequest) returns (GetUserFlagsResponse);

// GetUserFlags gets user flags for unauthenticated users
rpc GetUnauthenticatedUserFlags(GetUnauthenticatedUserFlagsRequest) returns (GetUnauthenticatedUserFlagsResponse);
}

message RegisterRequest {
// PublicKey the public key that is authorized to perform actions on the
// registered users behalf.
common.v1.PublicKey public_key = 1;
common.v1.PublicKey public_key = 1 [(validate.rules).message.required = true];

// Signature of this message (without the signature), using the provided keypair.
common.v1.Signature signature = 2;
common.v1.Signature signature = 2 [(validate.rules).message.required = true];
}
message RegisterResponse {
Result result = 1;
Expand All @@ -33,16 +42,19 @@ message RegisterResponse {
INVALID_SIGNATURE = 1;
DENIED = 2;
}

// The UserId associated with the account.
common.v1.UserId user_id = 2;
}

message LoginRequest {
// Timestamp is the timestamp the request was generated
//
// The server may reject the request if the timestamp is too far off
// the current (server) time. This is to prevent replay attacks.
google.protobuf.Timestamp timestamp = 1;
common.v1.Auth auth = 2;
google.protobuf.Timestamp timestamp = 1 [(validate.rules).timestamp.required = true];

common.v1.Auth auth = 2 [(validate.rules).message.required = true];
}
message LoginResponse {
Result result = 1;
Expand All @@ -51,12 +63,17 @@ message LoginResponse {
INVALID_TIMESTAMP = 1;
DENIED = 2;
}

common.v1.UserId user_id = 2;
}

message GetUserFlagsRequest {
common.v1.UserId user_id = 1;
common.v1.Auth auth = 2;
common.v1.UserId user_id = 1 [(validate.rules).message.required = true];

common.v1.Auth auth = 2 [(validate.rules).message.required = true];

common.v1.Platform platform = 3;

common.v1.CountryCode country_code = 4;
}
message GetUserFlagsResponse {
Expand All @@ -65,26 +82,34 @@ message GetUserFlagsResponse {
OK = 0;
DENIED = 1;
}

UserFlags user_flags = 2;
}

message GetUnauthenticatedUserFlagsRequest {
common.v1.Platform platform = 1;

common.v1.CountryCode country_code = 2;
}
message GetUnauthenticatedUserFlagsResponse {
Result result = 1;
enum Result {
OK = 0;
}

UserFlags user_flags = 2;
}

message UserFlags {
// Is this a fully registered account using IAP for account creation?
bool is_registered_account = 1;

// Is this user associated with a Flipcash staff member?
bool is_staff = 2;

// Does this user require IAP for registration in the account creation flow?
bool requires_iap_for_registration = 3;

enum OnRampProvider {
UNKNOWN = 0;
COINBASE_VIRTUAL = 1;
Expand All @@ -96,20 +121,28 @@ message UserFlags {
BACKPACK = 7;
BASE = 8;
}

// The set of supported on ramp providers for the user, based on their platform
// and locale if provided
repeated OnRampProvider supported_on_ramp_providers = 4 ;
repeated OnRampProvider supported_on_ramp_providers = 4 [(validate.rules).repeated = {
min_items: 0
max_items: 256
}];

// The preferred on ramp provider for this user. If the value is UNKNOWN, client
// should show the list of all supported providers.
OnRampProvider preferred_on_ramp_provider = 5;

// The minumum build number for this user. If their build number is less than the
// provided value, client should show a forced upgrade screen.
uint32 min_build_number = 6;

// Exchange data timeout for sequential give/grabs for bills
google.protobuf.Duration bill_exchange_data_timeout = 7;

// USDF amount, in quarks, that must be purchased when launching a new currency
uint64 new_currency_purchase_amount = 8;

// USDF amount, in quarks, that must be paid in a fee when launching a new currency
uint64 new_currency_fee_amount = 9;
}
Original file line number Diff line number Diff line change
@@ -1,59 +1,88 @@
syntax = "proto3";

package flipcash.activity.v1;

option go_package = "github.com/code-payments/flipcash2-protobuf-api/generated/go/activity/v1;activitypb";
option java_package = "com.codeinc.flipcash.gen.activity.v1";
option objc_class_prefix = "FPBActivityV1";

import "activity/v1/model.proto";
import "common/v1/common.proto";
import "validate/validate.proto";

service ActivityFeed {
// GetLatestNotifications gets the latest N notifications in a user's
// activity feed. Results will be ordered by descending timestamp.
rpc GetLatestNotifications(GetLatestNotificationsRequest) returns (GetLatestNotificationsResponse);

// GetPagedNotifications gets all notifications using a paging API.
rpc GetPagedNotifications(GetPagedNotificationsRequest) returns (GetPagedNotificationsResponse);

// GetBatchNotifications gets a batch of notifications by ID.
rpc GetBatchNotifications(GetBatchNotificationsRequest) returns (GetBatchNotificationsResponse);
}

message GetLatestNotificationsRequest {
// The activity feed to fetch notifications from
ActivityFeedType type = 1;
ActivityFeedType type = 1 [(validate.rules).enum.in = 1];

// Maximum number of notifications to return. If <= 0, the server default is used
int32 max_items = 2;
common.v1.Auth auth = 3;
int32 max_items = 2 [(validate.rules).int32.lte = 1024];

common.v1.Auth auth = 3 [(validate.rules).message.required = true];
}

message GetLatestNotificationsResponse {
Result result = 1;
enum Result {
OK = 0;
DENIED = 1;
}
repeated Notification notifications = 2 ;

repeated Notification notifications = 2 [(validate.rules).repeated = {
max_items: 1024
}];
}

message GetPagedNotificationsRequest {
// The activity feed to fetch notifications from
ActivityFeedType type = 1;
common.v1.QueryOptions query_options = 2;
common.v1.Auth auth = 3;
ActivityFeedType type = 1 [(validate.rules).enum.in = 1];

common.v1.QueryOptions query_options = 2 [(validate.rules).message.required = true];

common.v1.Auth auth = 3 [(validate.rules).message.required = true];
}

message GetPagedNotificationsResponse {
Result result = 1;
enum Result {
OK = 0;
DENIED = 1;
}
repeated Notification notifications = 2 ;

repeated Notification notifications = 2 [(validate.rules).repeated = {
max_items: 1024
}];
}

message GetBatchNotificationsRequest {
repeated NotificationId ids = 1 ;
common.v1.Auth auth = 2;
repeated NotificationId ids = 1 [(validate.rules).repeated = {
min_items: 1
max_items: 1024
}];

common.v1.Auth auth = 2 [(validate.rules).message.required = true];
}

message GetBatchNotificationsResponse {
Result result = 1;
enum Result {
OK = 0;
DENIED = 1;
NOT_FOUND = 2;
}
repeated Notification notifications = 2 ;

repeated Notification notifications = 2 [(validate.rules).repeated = {
max_items: 1024
}];
}
Loading
Loading