diff --git a/.gitea/workflows/buf-ci.yaml b/.gitea/workflows/buf-ci.yaml new file mode 100644 index 0000000..4603cb4 --- /dev/null +++ b/.gitea/workflows/buf-ci.yaml @@ -0,0 +1,77 @@ +name: Buf CI +on: + push: + tags: + - v* + +permissions: + contents: read + pull-requests: write + packages: write + +jobs: + buf: + runs-on: ubuntu-latest + steps: + - uses: actions/setup-go@v5 + with: + go-version: ">=1.23.0" + - uses: bufbuild/buf-setup-action@v1.47.2 + - uses: actions/checkout@v4 + with: + token: ${{ gitea.token }} + path: ./ + + - name: install tea cli and init + run: | + mkdir tmp && cd tmp + curl -SsOL https://dl.gitea.com/tea/main/tea-main-linux-amd64.xz + apt install xz-utils -y >/dev/null + xz -d tea-main-linux-amd64.xz + mv tea-main-linux-amd64 /usr/bin/tea + chmod +x /usr/bin/tea + cd .. + rm -rf tmp + tea --version + tea login add \ + --name ${{ gitea.server_url }} \ + --token ${{ secrets.PROD_REG_TOKEN }} \ + --url ${{ gitea.server_url }} + - run: go install google.golang.org/protobuf/cmd/protoc-gen-go@latest + - run: go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest + - run: go install github.com/pseudomuto/protoc-gen-doc/cmd/protoc-gen-doc@latest + - run: npm install --save @bufbuild/protobuf @bufbuild/protoc-gen-es @bufbuild/buf + - run: buf --version + - run: "export PATH=$PATH:./node_modules/.bin\nbuf generate \n" + - name: tar files + run: | + ls -l ./stub + for out in go ts doc; do + tar czf .res/${out}.tar.gz ./stub/${out}/ + done + tar czf ./.res/src.tar.gz $(find -type f -name "*.proto") + tea r c \ + --title "${{ gitea.ref_name }}" \ + --tag "${{ gitea.ref_name }}" \ + -a ./.res/src.tar.gz \ + -a ./.res/go.tar.gz \ + -a ./.res/doc.tar.gz \ + -a ./.res/ts.tar.gz \ + + # - run: | + # if [ -n ${{ gitea.ref_name }} ]; then + # mkdir .res + # for out in go ts doc; do + # echo releasing ${out} ... + # tar czf .res/${out}.tar.gz ./stub/${out}/ + # curl -Ss --user nfel:${{ secrets.PROD_REG_TOKEN }}\ + # --upload-file .res/${out}.tar.gz \ + # ${{ gitea.server_url }}/api/packages/Kahroba/generic/proto/${{ gitea.ref_name }}/${out}.tar.gz + # done + # echo releasing proto ... + # tar czf ./.res/src.tar.gz $(find -type f -name "*.proto") + # curl -Ss --user nfel:${{ secrets.PROD_REG_TOKEN }}\ + # --upload-file ./.res/src.tar.gz \ + # ${{ gitea.server_url }}/api/packages/Kahroba/generic/proto/${{ gitea.ref_name }}/src.tar.gz + # fi + # - run: | diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a74385c --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.idea +gen/go +stub +node_modules +yarn.lock +package-lock.json diff --git a/README.md b/README.md index e69de29..fc7d41d 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,3 @@ +# Protobuf with fangs + +![Build Status](https://git.kahrobatoken.com/Kahroba/proto/actions/workflows/buf-ci.yaml/badge.svg?branch=v2) diff --git a/alert/v1/msg.proto b/alert/v1/msg.proto new file mode 100644 index 0000000..34a856c --- /dev/null +++ b/alert/v1/msg.proto @@ -0,0 +1,76 @@ +syntax = "proto3"; + +package alert.v1; + +import "auth/v1/msg.proto"; + +// Importance of given event +enum Importance { + LOW = 0; // Low Severity ( unimportant and can be ignored ) + MEDIUM = 1; // MEDIUM Severity + HIGH = 2; // High Severity + CRITICAL = 3; // CRITICAL Severity ( can cause panics and data lost ) +} + +enum LogType { + TYPE_UNKNOWN = 0; + TYPE_SMS = 1; + TYPE_EMAIL = 2; + TYPE_PUSH = 3; +} + +enum LogLevel { + LVL_UNKNOWN = 0; + LVL_INFO = 1; + LVL_SUCCESS = 2; + LVL_WARN = 3; + LVL_ERROR = 4; +} + +enum LogSource { + SRC_UNKNOWN = 0; + SRC_USER = 1; + SRC_SYSTEM = 2; + SRC_WALLET = 3; +} + + +message Meta { + uint32 created_at_ts = 1; + uint32 updated_at_ts = 2; + uint32 blamer_id = 3; // User ID of person who made the change +} + +message LogEvent { + auth.v1.InternalIAM iam = 1; + optional uint64 id = 2; // Record Id of Log stored in db + LogSource source = 3; + Importance importance = 4; + LogLevel level = 5; + string content = 6; + Meta meta = 7; +} + +message LogEventList { + repeated LogEvent events = 1; +} +/* + Internal Msg +*/ + +message SMSChangeLog { + uint32 when_ts = 1; + string what = 2; +} + +message SMS { + string recipient = 1; // recipient + string text = 2; + optional string sender = 3; + Meta meta = 4; + repeated SMSChangeLog change_log = 5; +} + +message SMSList { + repeated SMS sms = 1; +} diff --git a/alert/v1/srv.proto b/alert/v1/srv.proto new file mode 100644 index 0000000..0de2f2e --- /dev/null +++ b/alert/v1/srv.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + +package alert.v1; + +import "alert/v1/msg.proto"; +import "base/v1/msg.proto"; + +service AlertSrv { + rpc NotificationSrvHealth(base.v1.Empty) returns (base.v1.StatusRes); + rpc Emit(LogEvent) returns (base.v1.StatusRes) {} + // rpc Update(LogEvent) returns (base.v1.StatusRes) {} + // rpc Get(AlertFilter) returns (base.v1.StatusRes) {} +} + diff --git a/auth/v1/internal_srv.proto b/auth/v1/internal_srv.proto new file mode 100644 index 0000000..a06d2e5 --- /dev/null +++ b/auth/v1/internal_srv.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; + +package auth.v1; + +import "auth/v1/msg.proto"; +import "base/v1/msg.proto"; + +service InternalAuthorizationService { + rpc InternalAuthorizationSrvHealth(base.v1.Empty) returns (base.v1.StatusRes); + rpc LookUpName(LookUpNameReq) returns (LookUpNameRes) {} + // This meant to only be used in a worker process + rpc FetchBasicUserInfoList(base.v1.Empty) returns (BasicUserInfoList) {} + + // rpc AuthorizationDeleteCache(base.v1.Empty) returns (base.v1.StatusRes); + rpc InitPermissionsForRoutes(InternalInitRoutesReq) returns (base.v1.StatusRes) {} + rpc GetUserIdentityBasic(GetUserReq) returns (UserIdentityBasic) {} + rpc GetUserIAM(GetUserReq) returns (InternalIAM) {} +} diff --git a/authorization_message.proto b/auth/v1/msg.proto similarity index 61% rename from authorization_message.proto rename to auth/v1/msg.proto index 415b2d6..d7e4cf8 100644 --- a/authorization_message.proto +++ b/auth/v1/msg.proto @@ -1,6 +1,6 @@ syntax = "proto3"; -package authorization; +package auth.v1; /* Internal @@ -19,7 +19,7 @@ message InternalRoute { message Role { int64 id = 1; string title = 2; - string Key = 3; + string key = 3; string type = 4; } message Permission { @@ -32,6 +32,9 @@ message Permission { message PermissionList { repeated Permission list = 1; + uint32 page_no = 2; + uint32 page_size = 3; + uint32 total_count = 4; } /* @@ -40,6 +43,7 @@ message PermissionList { message UserSendOtpReq { string mobile = 1; + string referral_code = 2; } message UserSendOtpRes { int64 expired_at = 1; @@ -52,6 +56,7 @@ message UserSendOtpRes { message UserLoginReq { string mobile = 1; string otp_code = 2; + string referral_code = 3; } message UserRefreshTokenReq { string refresh_token = 1; @@ -60,6 +65,7 @@ message UserAccessTokenRes { string access_token = 1; int64 access_expired_at = 2; string refresh_token = 3; + InternalIAM iam = 4; } /* @@ -75,17 +81,28 @@ message CheckIAMReq { message InternalIAM { User user = 1; IdentityBasic identity = 2; - repeated Company company = 3; } + message IdReqWithIAM { int64 id = 1; InternalIAM iam = 2; } + +message IdReqWithIAMAndTFA { + int64 id = 1; + InternalIAM iam = 2; + TFA tfa = 6; +} + message ReqWithIAMAndParams { InternalIAM iam = 1; optional bool accepted = 2; } +message ReqWithOptionalIAM { + optional InternalIAM iam = 1; +} + /* User */ @@ -94,12 +111,31 @@ message GetUserReq { string national_id = 2; } +enum UserStatus { + USER_STATUS_CREATED = 0; + + USER_STATUS_VALID_LV1 = 1; + USER_STATUS_VALID_LV2 = 2; + USER_STATUS_VALID_LV3 = 3; + + USER_STATUS_DISABLED = -1; + USER_STATUS_BANNED = -2; + USER_STATUS_DELETED = -3; +} + message User { int64 id = 1; string national_id = 2; string mobile = 3; string email = 4; - repeated int64 roles = 5; + UserStatus status = 5; + repeated int64 roles = 6; + int64 referrer_user_id = 7; +} + +message UserAddress { + string postal_code = 2; + string user_address = 3; } message Company { @@ -110,6 +146,7 @@ message Company { bool can_provide_bnpl = 5; } +// Identity is bound to current user's real identity message Identity { string national_id = 1; string national_serial_id = 2; @@ -131,14 +168,17 @@ message Identity { string updated_at = 18; string created_at = 19; string email = 20; - string mobile = 21; + string mobile = 21; optional Company company = 22; optional string employee_info = 23; + string pub_key = 24; + optional UserAddress user_address = 25; } message IdentityBasic { string first_name = 1; string last_name = 2; + optional Company company = 3; } message UserIdentityBasic { @@ -147,6 +187,8 @@ message UserIdentityBasic { string mobile = 3; string first_name = 4; string last_name = 5; + string wallet_address = 6; + bool is_identity_verified = 7; } message UserUpdateIdentityReq { @@ -154,6 +196,7 @@ message UserUpdateIdentityReq { string national_id = 2; string birthdate = 3; string email = 4; + optional UserAddress user_address = 5; } message UserUpdateBankInfoReq { @@ -165,14 +208,20 @@ message UserUpdateBankInfoReq { message BankInfoList { repeated BankInfo list = 1; + uint32 page_no = 2; + uint32 page_size = 3; + uint32 total_count = 4; } -// Status 0: Fail Verify, 1: Verified, 2: Does not Match user's credential +// Status 0: Fail Verify, 1: Verified, 2: Does not Match user's credential , 3: +// Closed for potential fraud enum BankInfoStatusEnum { FAIL_VERIFY = 0; VERIFIED = 1; DOES_NOT_MATCH = 2; + CLOSED = 3; } + message BankInfo { int64 id = 1; string deposit_number = 2; @@ -184,16 +233,13 @@ message BankInfo { } /* Two Factor Authentication */ -message IdReqWithIAMAndTFA { - int64 id = 1; - InternalIAM iam = 2; - string tfa_code = 3; -} message TFAReq { InternalIAM iam = 1; optional string mobile = 2; optional string email = 3; optional string reason = 4; // issued jwt reason -> can be login, redeem, withdrawal + optional int64 id = 5; + optional TfaStateEnum state = 6; } // Two Factor Authentication Exchange Response @@ -205,6 +251,58 @@ message TFAExRes { message CheckTFAReq { InternalIAM iam = 1; string code = 2; - optional string algorithm = 3; - optional string reason = 4; // Can be later used as a lookup + TFAReq req = 3; + // optional string algorithm = 3; + // optional string reason = 4; // Can be later used as a lookup + // optional string id = 5; + // optional TfaStateEnum state = 6; +} + +message TFA { + TfaStateEnum state = 1; + int64 code = 2; + int64 id = 3; +} + +enum TfaStateEnum { + TFA_STATE_ENUM_UNSPECIFIED = 0; + LOGIN = 1; + INTERNAL_TRANSFER = 2; + EXTERNAL_TRANSFER = 3; + REDEEM_TOKEN = 4; + MARKET_PLACE_MAKER = 5; + MARKET_PLACE_TAKER = 6; + MARKET_PLACE_ORDER_CANCEL = 7; + IRT_WITHDRAWAL = 8; + IRT_DEPOSIT = 9; +} + +message Recipient { + string key = 1; + optional string first_name = 2; + optional string last_name = 3; + optional int64 user_id = 4; + optional string public_key = 5; +} + +message LookUpNameReq { + Recipient recipient = 1; +} + +message LookUpNameRes { + Recipient recipient = 1; +} + +message BasicUserInfo { + string name = 1; + string national_id = 2; + string pub_key = 3; + int64 user_id = 4; +} + +message BasicUserInfoList { + repeated BasicUserInfo list = 1; + uint32 page_no = 2; + uint32 page_size = 3; + uint32 total_count = 4; } diff --git a/auth/v1/srv.proto b/auth/v1/srv.proto new file mode 100644 index 0000000..d90c2ea --- /dev/null +++ b/auth/v1/srv.proto @@ -0,0 +1,37 @@ +syntax = "proto3"; + +package auth.v1; + +import "auth/v1/msg.proto"; +import "base/v1/msg.proto"; + +service AuthorizationService { + rpc AuthorizationSrvHealth(base.v1.Empty) returns (base.v1.StatusRes); + + rpc CheckIAM(CheckIAMReq) returns (InternalIAM) {} + + rpc SendLoginOTP(UserSendOtpReq) returns (UserSendOtpRes) {} + rpc LoginWithOTP(UserLoginReq) returns (UserAccessTokenRes) {} + rpc GetAccessTokenByRefreshToken(UserRefreshTokenReq) returns (UserAccessTokenRes) {} + + rpc GetUserPermission(InternalIAM) returns (PermissionList) {} + + rpc GetIdentity(InternalIAM) returns (Identity) {} + rpc UpdateIdentity(UserUpdateIdentityReq) returns (base.v1.StatusRes) {} + + rpc GetBankInfoList(ReqWithIAMAndParams) returns (BankInfoList) {} + rpc UpdateBankInfo(UserUpdateBankInfoReq) returns (base.v1.StatusRes) {} + rpc RemoveBankInfo(IdReqWithIAM) returns (base.v1.StatusRes) {} + + rpc GetUser(GetUserReq) returns (User) {} + + // Two Factor Authentication + // For now it's only SMS-OTP - later will be Email-OTP or other methods can be + // added For HMAC-OTP there won't be a need to call this api + rpc ProcessTFAReq(TFAReq) returns (base.v1.StatusRes) {} + + // For HMAC-OTP an initialization step must be added to exchange keys + rpc InitTFAReq(InternalIAM) returns (TFAExRes) {} + + rpc CheckTFACode(CheckTFAReq) returns (base.v1.StatusRes) {} +} diff --git a/authorization.proto b/authorization.proto deleted file mode 100644 index 3179650..0000000 --- a/authorization.proto +++ /dev/null @@ -1,38 +0,0 @@ -syntax = "proto3"; - -package authorization; - -import "authorization_message.proto"; -import "base_message.proto"; - -service AuthorizationService { - rpc InternalAuthorizationDeleteCache(base.Empty) returns (base.StatusRes); - rpc InternalInitRoutes(InternalInitRoutesReq) returns (base.StatusRes) {} - rpc InternalGetUserIdentityBasic(GetUserReq) returns (UserIdentityBasic) {} - rpc InternalGetUserIAM(GetUserReq) returns (InternalIAM) {} - rpc CheckIAM(CheckIAMReq) returns (InternalIAM) {} - - rpc UserLoginSendOTP(UserSendOtpReq) returns (UserSendOtpRes) {} - rpc UserLoginWithOTP(UserLoginReq) returns (UserAccessTokenRes) {} - rpc UserGetAccessTokenByRefreshToken(UserRefreshTokenReq) - returns (UserAccessTokenRes) {} - - rpc UserGetUserPermission(InternalIAM) returns (PermissionList) {} - - rpc UserGetIdentity(InternalIAM) returns (Identity) {} - rpc UserUpdateIdentity(UserUpdateIdentityReq) returns (base.StatusRes) {} - - rpc UserGetBankInfoList(ReqWithIAMAndParams) returns (BankInfoList) {} - rpc UserUpdateBankInfo(UserUpdateBankInfoReq) returns (base.StatusRes) {} - rpc UserRemoveBankInfo(IdReqWithIAM) returns (base.StatusRes) {} - - rpc GetUser(GetUserReq) returns (User) {} - - // Two Factor Authentication - // For now it's only SMS-OTP - later will be Email-OTP or other methods can be - // added For HMAC-OTP there won't be a need to call this api - rpc SendTFAReq(TFAReq) returns (base.StatusRes) {} - // For HMAC-OTP an initialization step must be added to exchange keys - rpc InitTFAReq(InternalIAM) returns (TFAExRes) {} - rpc CheckTFACode(CheckTFAReq) returns (base.StatusRes) {} -} diff --git a/base/v1/msg.proto b/base/v1/msg.proto new file mode 100644 index 0000000..4f85910 --- /dev/null +++ b/base/v1/msg.proto @@ -0,0 +1,26 @@ +syntax = "proto3"; + +package base.v1; + +message Empty {} + +message StatusRes { + bool success = 1; +} +message IdRes { + int64 id = 1; +} +message IdReq { + int64 id = 1; +} + +message YesNoRes { + bool yes = 1; +} + +message PaginationRespSample { + + uint32 page_no = 2; + uint32 page_size = 3; + uint32 total_count = 4; +} diff --git a/base_message.proto b/base_message.proto deleted file mode 100644 index 0ac5832..0000000 --- a/base_message.proto +++ /dev/null @@ -1,15 +0,0 @@ -syntax = "proto3"; - -package base; - -message Empty {} - -message StatusRes { - bool success = 1; -} -message IdRes { - int64 id = 1; -} -message IdReq { - int64 id = 1; -} diff --git a/buf.gen.yaml b/buf.gen.yaml new file mode 100644 index 0000000..4bc8897 --- /dev/null +++ b/buf.gen.yaml @@ -0,0 +1,62 @@ +--- +version: v2 +clean: true +managed: + enabled: true + override: + - file_option: go_package_prefix + # FIXME: Change this to you're go.mod package name + value: github.com/nfel +plugins: + # NOTE: golang + # - remote: buf.build/grpc/go + # NOTE: grpc + # go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest + - local: protoc-gen-go-grpc + out: stub/go + # NOTE: PB files + # go install google.golang.org/protobuf/cmd/protoc-gen-go@latest + - local: protoc-gen-go + # - remote: buf.build/protocolbuffers/go:v1.30.0 + out: stub/go + # NOTE: doc + - local: protoc-gen-doc + opt: html,index.html,source_relative + out: stub/doc/html + - local: protoc-gen-doc + opt: markdown,index.md,source_relative + out: stub/doc/md + # # NOTE: Gateway + # # - remote: buf.build/grpc-ecosystem/gateway:v2.16.2 + - local: protoc-gen-grpc-gateway + out: stub/go + opt: + - standalone=true + - generate_unbound_methods=true + # # NOTE: SWAGGER json files + # # - remote: buf.build/grpc-ecosystem/openapiv2:v2.16.2 + # - local: protoc-gen-openapiv2 + # opt: import_prefix=github.com/nfel + # out: stub/go + # - local: protoc-gen-go-gin + # opt: + # # - plugin=handler + # # - plugin=service + # # - plugin=mix + # out: stub/go + # NOTE: Typescript + # - remote: buf.build/bufbuild/es:v2.2.2 + # # opt: import_prefix=github.com/nfel + # out: stub/ts + - local: protoc-gen-es + out: stub/ts + opt: target=ts + + # - local: protobuf-ts + # # opt: import_prefix=github.com/nfel + # out: stub/ts +inputs: + - directory: ./ + # - git_repo: ssh://git@5.34.204.11/Kahroba/proto + # branch: v2 + diff --git a/buf.yaml b/buf.yaml index 2abbb7b..5c77bb7 100644 --- a/buf.yaml +++ b/buf.yaml @@ -1,12 +1,14 @@ --- -version: v1 +version: v2 +breaking: + use: + - FILE + - PACKAGE lint: use: - - DEFAULT -# disallow_comment_ignores: false -# # The default behavior of this key has changed from v1 -# enum_zero_value_suffix: _UNSPECIFIED -# rpc_allow_same_request_response: true -# rpc_allow_google_protobuf_empty_requests: false -# rpc_allow_google_protobuf_empty_responses: false -# service_suffix: Service + - BASIC + - PACKAGE_SAME_GO_PACKAGE + - PACKAGE_NO_IMPORT_CYCLE + - IMPORT_USED +modules: + - path: ./ diff --git a/errors/v1/msg.proto b/errors/v1/msg.proto new file mode 100644 index 0000000..bfa12f1 --- /dev/null +++ b/errors/v1/msg.proto @@ -0,0 +1,141 @@ +syntax = "proto3"; + +package errors.v1; + +enum ErrCode { + // General errors + OK = 0; + FAILED = 1; + SERVER_ERROR = 2; + INTERNAL = 3; + UNAVAILABLE = 4; + + // Authentication and authorization errors + UNAUTHENTICATED = 1000; + PERMISSION_DENIED = 1001; + ACCESS_DENIED = 1002; + FORBIDDEN = 1003; + BAD_AUTH = 1004; + SESSION_EXPIRED = 1005; + USER_KYC_LV1_NOT_FOUND = 1006; + USER_KYC_LV2_NOT_FOUND = 1007; + + // Argument validation errors + INVALID_ARGUMENT = 2000; + INVALID_ARGUMENT_EMPTY_VALUE = 2001; + INVALID_ARGUMENT_INVALID_VALUE = 2002; + INVALID_ARGUMENT_INVALID_FORMAT = 2003; + INVALID_ARGUMENT_MISSING_RECIPIENT = 2004; + INVALID_ARGUMENT_EMPTY_ID = 2005; + INVALID_ARGUMENT_COMPANY_REQUIRED = 2006; + INVALID_ARGUMENT_UNKNOWN_TRX_TYPE = 2007; + INVALID_ARGUMENT_INVALID_CODE = 2008; + INVALID_ARGUMENT_RRN = 2009; + INVALID_ARGUMENT_MOBILE_NUMBER = 2010; + INVALID_ARGUMENT_IBAN_NUMBER = 2011; + INVALID_ARGUMENT_UNKNOWN_TYPE = 2012; + INVALID_ARGUMENT_BAD_STELLAR_ADDRESS = 2013; + INVALID_ARGUMENT_ZERO_AMOUNT = 2014; + INVALID_BUY_AMOUNT = 2015; + INVALID_BUY_AMOUNT_MAX = 2016; + INVALID_BUY_AMOUNT_MIN = 2017; + INVALID_ARGUMENT_TFA_REQUIRED = 2018; + + // Resource errors + NOT_FOUND = 3000; + ALREADY_EXISTS = 3001; + ASSET_NOT_FOUND = 3002; + WALLET_NOT_FOUND = 3003; + AGREEMENT_NOT_FOUND = 3004; + DISCOUNT_NOT_FOUND = 3005; + BANK_INFO_NOT_FOUND = 3007; + RECIPIENT_NOT_FOUND = 3008; + USER_NOT_FOUND = 3009; + INVALID_REFERRAL_CODE = 3011; + MARKET_AGREEMENT_ALREADY_ACCEPTED = 3010; + + // Resource state errors + ASSET_NOT_ACTIVE = 4000; + WALLET_NOT_ACTIVE = 4001; + DISCOUNT_NOT_ACTIVE = 4002; + RECIPIENT_NOT_ACTIVE = 4003; + + // Transaction errors + TRX_STATUS_UNKNOWN = 5000; + TRX_STATUS_PENDING = 5001; + TRX_STATUS_FAILED = 5002; + TRX_STATUS_SUCCESS = 5003; + TRX_STATUS_CANCELED = 5004; + TRX_STATUS_EXPIRED = 5005; + TRX_STATUS_CREATED = 5006; + TRX_STATUS_SUSPENDED = 5007; + + // Stellar errors + STELLAR_ERR_ESTABLISH_TRUST_LINE = 6000; + STELLAR_ERR_CREATE_ACCOUNT = 6001; + STELLAR_ERR_TRANSFER = 6002; + STELLAR_ERR_GET_ACCOUNT = 6003; + STELLAR_ERR_LOW_FEE = 6004; + STELLAR_ERR_LOW_RESERVE = 6005; + + // Market-related errors + MARKET_ORDER_NOT_FOUND = 3006; + MARKET_ORDER_ALREADY_CREATED = 7020; + MARKET_ORDER_ALREADY_OPENED = 7021; + MARKET_ORDER_COMPLETED = 7022; + MARKET_ORDER_CANCELED = 7023; + MARKET_ORDER_FAILED = 7024; + MARKET_ORDER_UNKNOWN = 7025; + MARKET_ORDER_UNSUPPORTED_PARTICIPANT_TYPE = 7045; + ASSET_CAN_NOT_BUY = 7026; + ASSET_BUY_PRICE_IS_ZERO = 7019; + MARKET_ORDER_MATCHING_ERR_REFUND = 7128; + + // Specific errors + IBAN_MISS_MATCH = 7003; + SHAHKAR_FAILED = 7004; + SHAHKAR_SYSTEM_ERROR = 7005; + PENDING_OTP_ALREADY_EXISTS = 7006; + INVALID_OTP = 7007; + BAD_BANK_INFO = 7008; + NOT_ACCEPT_LEGAL = 7009; + NEED_TRUST_LINE = 7010; + EXPIRED = 7011; + INVALID_DISCOUNT_CODE = 7012; + ASSET_INVALID = 7013; + LOW_REQUEST_AMOUNT = 7014; + AGREEMENT_ALREADY_ACCEPTED = 7015; + CONTRACT_ALREADY_GENERATED = 7016; + CONTRACT_NOT_FOUND = 7080; + NIL_AUTH = 7017; + CAN_NOT_BUY_AND_DEPOSIT = 7018; + WHITELIST_ALREADY_USED = 7027; + NATIONAL_ID_IS_EMPTY = 7028; + NOT_ENOUGH_BALANCE = 7029; + ASSET_MAX_BALANCE_REACHED = 7030; + WALLET_IS_NOT_IN_WHITE_LIST = 7031; + RECIPIENT_IS_NOT_IN_WHITE_LIST = 7032; + MOBILE_NATIONAL_ID_MISS_MATCH = 7033; + NOT_ENOUGH_LOCKED_BALANCE = 7034; + NOT_ENOUGH_BALANCE_TO_LOCK = 7035; + IPG_GEN_TOKEN_FAILED = 7036; + USER_INFO_NATIONAL_ID_BIRTHDATE_MISS_MATCH = 7037; + + + // Server errors + SERVER_ERROR_FREEZED_BALANCE_NEGATIVE = 8000; + SERVER_ERROR_NIL_DB_TX = 8001; + SERVER_ERROR_TFA_TEMPLATE_NOT_FOUND = 8002; + + // Person-related errors + GET_PERSON_FAILED = 9000; + USER_NOT_VERIFIED = 9001; + USER_BANNED = 9002; + USER_DELETED = 9003; + USER_DISABLED = 9004; +} + +message ErrorMsg { + ErrCode code = 1; + map details = 2; +} diff --git a/market/v1/msg.proto b/market/v1/msg.proto new file mode 100644 index 0000000..9f21643 --- /dev/null +++ b/market/v1/msg.proto @@ -0,0 +1,196 @@ +syntax = "proto3"; + +package market.v1; + +import "auth/v1/msg.proto"; +import "wallet/v1/msg.proto"; + +enum MarketParticipantType { + MO_PT_UNKNOWN = 0; + MO_PT_MAKER = 1; + MO_PT_TAKER = 2; +} + +enum MarketOrderSide { + MO_UNKNOWN = 0; + MO_BUY = 1; + MO_SELL = 2; +} + +enum MarketOrderStatus { + MO_UNKNOWN_MP_STATUS = 0; // Unknown + MO_CREATED = 1; // Order is just created and awaits confirmation + MO_OPEN = 2; // Order is open and waiting to be completed + MO_CANCEL = 3; // Cancelled by user + MO_COMPLETED = 4; // Order is completed + MO_FAILED = 5; // Order is failed - bad trx , etc. + MO_REFUNDED = 6; // Order is refunded by platform to user due to regulation + // MO_EXPIRED = 7; // Order is expired +} + +message CalcMarketReq { + optional auth.v1.InternalIAM iam = 1; // For whitelist :') + int64 asset_id = 2; + int64 counter_asset_id = 3; + double amount = 4; + double unit_price = 5; + MarketParticipantType participant_type = 6; + wallet.v1.BuyAssetSide req_side = 7; // For Calculation : can be from asset or irt +} + +message CalcMarketRes { + double calculated_irt_amount = 1; + double calculated_asset_amount = 2; + wallet.v1.EffectiveCommission commission = 3; + MarketParticipantType participant_type = 4; + wallet.v1.BuyAssetSide req_side = 5; // For Calculation : can be from asset or irt +} + +message MPHistoryFilter {} +message MPListFilter {} +message MarketOrder { + uint64 id = 1; + uint64 trx_id = 2; + wallet.v1.Asset asset = 3; + wallet.v1.Asset counter_asset = 4; + double amount = 5; + double unit_price = 6; + double total_price = 7; + MarketOrderSide side = 8; + MarketOrderStatus status = 9; + int64 from = 10; + MarketParticipantType participant_type = 11; + auth.v1.UserIdentityBasic from_identity = 12; + wallet.v1.Commission commission = 13; + double completed_amount = 14; + double available_amount = 15; + string created_at = 16; + string updated_at = 17; + bool is_public = 18; + wallet.v1.TransactionList trx = 19; + repeated string tags = 20; + repeated string comment = 21; + optional MarketOrder source = 22; // purchase is done via this field + // repeated string attachments = 14; // possible files included by + // seller/buyer +} + +message MarketAssetListReq { + optional auth.v1.InternalIAM iam = 1; // If not set, will returns only public orders which are limited by a + optional uint32 page_no = 2; + optional uint32 page_size = 3; +} + +message MarketAssetList { + repeated wallet.v1.Asset list = 1; + uint32 page_no = 2; + uint32 page_size = 3; + uint32 total_count = 4; +} + +message MatchOrderReq { + auth.v1.InternalIAM iam = 1; + uint64 order_id = 2; + double amount = 3; + wallet.v1.BuyAssetSide req_side = 7; // For Calculation : can be from asset or irt + optional bool accepted_contract = 4; + optional auth.v1.TFA tfa = 5; +} + +message MatchOrderRes { + uint64 order_id = 1; + double calculated_irt_amount = 2; + double calculated_asset_amount = 3; + wallet.v1.EffectiveCommission commission = 4; + MarketOrderStatus status = 5; +} + +message MarketOrderList { + repeated MarketOrder list = 1; + uint32 page_no = 2; + uint32 page_size = 3; + uint32 total_count = 4; +} + +/* + * participant_type: IS Maker/Taker + * side: IS Buying/Selling + * req_side: IS input (amount) in irt/asset + * */ +message NewMarketReq { + auth.v1.InternalIAM iam = 1; + int64 asset_id = 2; + int64 counter_asset_id = 3; + double amount = 4; + double unit_price = 5; + // TODO: Change name + MarketParticipantType participant_type = 6; + // For Calculation : can be from asset or irt + wallet.v1.BuyAssetSide req_side = 7; + MarketOrderSide side = 8; + // TODO: maker market order as optional + optional uint64 maker_order_id = 9; +} + +enum MarketOrdersSortBy { + MO_SORT_UNKNOWN = 0; + MO_CREATED_AT_ASC = 1; + MO_CREATED_AT_DESC = 2; + MO_UNIT_PRICE_ASC = 3; + MO_UNIT_PRICE_DESC = 4; + MO_TOTAL_PRICE_ASC = 5; + MO_TOTAL_PRICE_DESC = 6; + MO_AVAILABLE_AMOUNT_ASC = 7; + MO_AVAILABLE_AMOUNT_DESC = 8; +} + +message OrderListFilter { + optional auth.v1.InternalIAM iam = 1; + optional string search = 3; + optional MarketOrderSide side = 4; + repeated MarketOrderStatus status = 5; + repeated string from = 6; + repeated string to = 7; + optional double starting_price = 8; + optional double ending_price = 9; + repeated uint64 asset = 10; + optional uint64 order_id = 11; + optional uint64 trx_id = 12; + optional bool is_public = 13; + optional uint64 maker_order_id = 15; + optional string from_date = 16; + optional string to_date = 17; + optional MarketParticipantType participant_type = 18; + optional MarketOrdersSortBy sort_by = 19; + optional uint32 page_no = 21; + optional uint32 page_size = 22; +} + +/* Contract */ +message ContractMarketRes { + string link = 1; + uint64 asset_id = 2; + uint64 agreement_id = 3; + uint64 transaction_id = 4; + string contract_hash = 5; + string contract_content = 6; +} + +message DeclineMarketContractReq { + auth.v1.InternalIAM iam = 1; + uint64 agreement_id = 2; +} + +message ConfirmMarketContractReq { + auth.v1.InternalIAM iam = 1; + uint64 agreement_id = 2; + optional auth.v1.TFA tfa = 3; +} + +message MarketContractReq { + auth.v1.InternalIAM iam = 1; + // uint64 asset_id = 2; + uint64 order_id = 2; // Maker OrderID + // double amount = 4; + // wallet.v1.BuyAssetSide req_side = 5; +} diff --git a/market/v1/srv.proto b/market/v1/srv.proto new file mode 100644 index 0000000..5a1ef52 --- /dev/null +++ b/market/v1/srv.proto @@ -0,0 +1,25 @@ +syntax = "proto3"; + +package market.v1; + +import "auth/v1/msg.proto"; +import "base/v1/msg.proto"; +import "market/v1/msg.proto"; + +service MarketplaceSrv { + rpc MarketplaceSrvHealth(base.v1.Empty) returns (base.v1.StatusRes); + + rpc GetMarketPubHistory(OrderListFilter) returns (MarketOrderList); // This is for public market + rpc GetUserMarketHistory(OrderListFilter) returns (MarketOrderList); // list of order + purchase related to buying an asset + rpc GetMarketOrderDet(auth.v1.IdReqWithIAM) returns (MarketOrder); // details of an order by id + rpc GetAllOrderList(OrderListFilter) returns (MarketOrderList); // list of all orders (seller and buyer combined) + rpc GetMarketAssetList(MarketAssetListReq) returns (MarketAssetList); // assets that can be listed in marketplace + + rpc CalcMarketOrder(CalcMarketReq) returns (CalcMarketRes); + + rpc CancelOrder(auth.v1.IdReqWithIAMAndTFA) returns (base.v1.StatusRes); // cancel an order + + rpc NewMarketOrder(NewMarketReq) returns (MarketOrder); // insert new buy order to market + rpc GenerateMarketContract(MarketContractReq) returns (ContractMarketRes); + rpc ConfirmMarketContract(ConfirmMarketContractReq) returns (base.v1.StatusRes); +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..b9a3d98 --- /dev/null +++ b/package.json @@ -0,0 +1,7 @@ +{ + "devDependencies": { + "@bufbuild/buf": "^1.47.2", + "@bufbuild/protobuf": "^2.2.2", + "@bufbuild/protoc-gen-es": "^2.2.2" + } +} diff --git a/template.buf.gen.yaml b/template.buf.gen.yaml new file mode 100644 index 0000000..ad3cf25 --- /dev/null +++ b/template.buf.gen.yaml @@ -0,0 +1,24 @@ +--- +version: v2 +clean: true +managed: + enabled: true + override: + - file_option: go_package_prefix + value: +plugins: + - remote: buf.build/grpc/go + out: stub/go + - remote: buf.build/protocolbuffers/go:v1.30.0 + out: stub/go + - local: protoc-gen-doc + opt: html,index.html,source_relative + out: stub/doc + - local: protoc-gen-grpc-gateway + out: stub/go + - local: protoc-gen-openapiv2 + out: stub/go +inputs: + - git_repo: ssh://git@5.34.204.11/Kahroba/proto + branch: v2 + diff --git a/wallet.proto b/wallet.proto deleted file mode 100644 index c7f0ac5..0000000 --- a/wallet.proto +++ /dev/null @@ -1,42 +0,0 @@ -syntax = "proto3"; - -package wallet; - -import "authorization_message.proto"; -import "base_message.proto"; -import "wallet_message.proto"; - -service WalletService { - rpc InternalWalletDeleteCache(base.Empty) returns (base.StatusRes); - rpc InternalCreateFederation(authorization.InternalIAM) returns (base.StatusRes); - - rpc AdminGetFederation(GetFederationReq) returns (Federation); - rpc UserGetFederation(authorization.InternalIAM) returns (Federation); - - rpc UserGetAssetList(base.Empty) returns (AssetList); - rpc AdminGetAssetList(base.Empty) returns (AssetList); - rpc GetAsset(GetAssetReq) returns (Asset); - - rpc UserInitWallet(UserInitWalletReq) returns (base.StatusRes); - rpc UserGetWalletList(authorization.InternalIAM) returns (WalletList); - rpc UserTransferAsset(UserTransferAssetReq) returns (UserTransferRes); - - rpc UserGetTransactionList(UserGetTransactionListReq) returns (TransactionList); - - rpc SaleGetToken(SaleGetTokenReq) returns (SaleGetTokenRes); - rpc SaleConfirm(SaleConfirmReq) returns (SaleConfirmRes); - rpc AdminManualSaleDeposit(SaleManualReq) returns (base.StatusRes); - - // BNPL - rpc GetBNPLList(base.Empty) returns (BNPLList); - rpc GetBNPLInfo(base.IdReq) returns (BNPLInfo); - rpc GetUserBNPLInfo(GetUserBNPLInfoReq) returns (UserBNPLResp); - rpc SubmitBNPLForm(UserBNPLReq) returns (base.StatusRes); - rpc UpdateBNPL(UserBNPLReq) returns (base.StatusRes); - rpc CancleBNPL(authorization.IdReqWithIAM) returns (base.StatusRes); - - // Redeem Token - rpc CalculateRedeemToken(RedeemTokenReq) returns (CalculateRedeemTokenRes); - rpc RedeemToken(RedeemTokenReq) returns (base.StatusRes); - rpc RedeemTokenList(authorization.ReqWithIAMAndParams) returns (RedeemTokenResList); -} diff --git a/wallet/v1/internal_srv.proto b/wallet/v1/internal_srv.proto new file mode 100644 index 0000000..d890e42 --- /dev/null +++ b/wallet/v1/internal_srv.proto @@ -0,0 +1,23 @@ +syntax = "proto3"; + +package wallet.v1; + +import "base/v1/msg.proto"; +import "wallet/v1/msg.proto"; + +service InternalWalletSrv { + rpc InternalWalletSrvHealth(base.v1.Empty) returns (base.v1.StatusRes); + + // Lock And Release Assets + rpc LockAsset(LockAssetReq) returns (base.v1.StatusRes); + rpc ReleaseAsset(LockAssetReq) returns (base.v1.StatusRes); + + rpc CollectCommission(CommissionReq) returns (CommissionRes); + rpc RefundCommission(RefundCommissionReq) returns (CommissionRes); + + // Calculate stellar pub-priv key based on national id + rpc GetPublicKeyByNationalID(NationalIDReq) returns (PubKeyRes); + + // Commission Logs + rpc InitReferrerCommissionLog(InitReferrerCommissionLogIn) returns (base.v1.Empty); +} diff --git a/wallet/v1/msg.proto b/wallet/v1/msg.proto new file mode 100644 index 0000000..013ed93 --- /dev/null +++ b/wallet/v1/msg.proto @@ -0,0 +1,842 @@ +syntax = "proto3"; + +package wallet.v1; + +import "auth/v1/msg.proto"; +import "base/v1/msg.proto"; + +/* + INTERNAL DATA; +*/ + +message InternalTransactionData { + int64 transaction_id = 1; +} + +/* + Federation +*/ + +message Federation { + int64 id = 1; + int64 user_id = 2; + string ed_public = 3; + string ed_public_hash = 4; + int32 status = 5; + string created_at = 6; + string system_wallet_address = 7; +} + +message GetFederationReq { + optional int64 federation_id = 1; + optional int64 user_id = 2; + optional string ed_public = 3; + optional string ed_public_hash = 4; +} + +/* + Wallet +*/ + +message UserInitWalletReq { + auth.v1.InternalIAM iam = 1; + int64 asset_id = 2; +} + +message WalletList { + repeated Wallet list = 1; + double available_balance = 3; + double locked_balance = 4; + double total_balance = 5; + + uint32 page_no = 6; + uint32 page_size = 7; + uint32 total_count = 8; +} + +message Wallet { + int64 id = 1; + int64 user_id = 2; + int64 asset_id = 3; + Asset asset_info = 4; + int64 federation_id = 5; + Federation federation_info = 6; + double balance = 7; + double frozen_balance = 8; + string updated_at = 9; + string created_at = 10; + string wallet_code = 11; + bool accepted_terms = 12; + bool is_locked = 13; +} + +message BalanceReq { + auth.v1.InternalIAM iam = 1; + int64 asset_id = 2; +} +message CheckBalanceReq { + auth.v1.InternalIAM iam = 1; + int64 asset_id = 2; + double amount = 3; // Checks if user have enough balance +} + +message BalanceRes { + double available_balance = 1; + double locked_balance = 2; + double total_balance = 3; +} + +/* + Asset +*/ + +message Asset { + int64 id = 1; + string name = 2; + string code = 3; + string issuer = 4; + string network_code = 5; + int32 decimal = 6; + double max_supply = 7; + string image = 8; + string description = 9; + string url = 10; + // int64 buy_unit_price = 11; + double buy_min_amount = 12; + double buy_max_amount = 13; + bool is_active = 20; + bool can_buy = 21; + bool can_sell = 22; + bool can_deposit = 23; + bool can_withdraw = 24; + bool can_trade = 25; + string updated_at = 29; + string created_at = 30; + repeated string images = 31; + repeated string videos = 32; + AssetStatus status = 33; + AssetMeta meta = 34; + AssetTokenType token_type = 35; + AssetPrice price = 36; + bool is_base_asset = 37; + bool is_locked = 38; + AssetType type = 39; +} + +enum AssetTokenType { + ASSET_NETWORK_TYPE_UNKNOWN = 0; + ASSET_NETWORK_TYPE_STELLAR_NATIVE = 1; + ASSET_NETWORK_TYPE_STELLAR_ALPHANUMERIC4 = 2; + ASSET_NETWORK_TYPE_STELLAR_ALPHANUMERIC12 = 3; + ASSET_NETWORK_TYPE_ERC20 = 4; +} + +enum AssetStatus { + ASSET_STATUS_UNKNOWN = 0; + ASSET_STATUS_ACTIVE = 1; + ASSET_STATUS_INACTIVE = 2; + ASSET_STATUS_SOON = 3; + ASSET_STATUS_FINISHED = 4; + ASSET_STATUS_EVALUATION = 5; + ASSET_STATUS_SUSPENDED = 6; +} + +enum AssetType { + ASSET_TYPE_UNKNOWN = 0; + ASSET_TYPE_PROJECT = 1; + ASSET_TYPE_CURRENCY = 2; + ASSET_TYPE_NETWORK_GAS = 3; +} + +message AssetList { + repeated Asset list = 1; + uint32 page_no = 2; + uint32 page_size = 3; + uint32 total_count = 4; +} + +message AssetFilter { + repeated int64 ids = 1; + repeated AssetType type = 2; // AssetType + repeated AssetType token_type = 3; // AssetType + repeated AssetStatus status = 4; + repeated string name = 5; + optional bool can_buy = 6; + optional bool can_sell = 7; + optional bool can_deposit = 8; + optional bool can_withdraw = 9; + optional bool can_trade = 10; + optional bool is_active = 11; + optional string search = 12; // Not yet implemented ! +} + +message AssetDiscountReq { + auth.v1.InternalIAM iam = 1; + string code = 2; + int64 asset_id = 3; + optional double amount = 4; // calculate discount amount +} + +message AssetDiscountRes { + uint64 id = 1; + string code = 2; + string expires_at = 3; + double static_amount = 4; + double percentage = 5; + double max_amount = 6; + double effective_amount = 7; // based of asset price and discount amount in req + optional int64 supported_asset = 8; +} + +message AssetPrice { + string updated_at = 1; + double market_price = 2; + double ico_price = 3; + double current_price = 4; +} + +message GetAssetReq { + optional int64 id = 1; + optional string code = 3; +} + +message AssetMeta { + PropertyMeta property = 1; +} + +message PropertyMeta { + string description = 1; + string builder_description = 2; + string white_paper_url = 3; + string expert_report_url = 4; + string project_catalog_url = 5; + string ownership_document_url = 6; + double total_area_meters = 7; + int32 total_unit_count = 8; + string usage_type = 9; + string completion_date = 10; + string user_agreement_url = 11; + float lat = 12; + float lng = 13; + string map_link = 14; + PropertyDetail detail = 15; +} + +message PropertyDetail { + repeated Content badge = 1; // 2> + repeated Content content = 2; // 4> +} + +message Content { + string label = 1; + string value = 2; + string value_type = 3; +} + +// Used for both locking and releasing asset :) +message LockAssetReq { + int64 asset_id = 1; + double amount = 2; + auth.v1.InternalIAM iam = 3; + optional auth.v1.TFA tfa = 4; // if request is not internal +} + +/* + BNPL - not really but close name +*/ + +message GetUserBNPLInfoReq { + auth.v1.InternalIAM iam = 1; + base.v1.IdReq id = 2; +} + +enum BNPLPaymentsStatus { + PENDING_PAYMENT = 0; + PAID = 1; + OVER_DUE = 2; + NOT_STARTED = 3; + NOT_YET_DUE = 4; + CANCELED = 5; + REJECTED = 6; +} +message BNPLPayments { + uint64 id = 1; + double amount = 2; + double amount_irr = 7; + bool is_paid = 3; + string due_date = 4; + string settlement_date = 5; + BNPLPaymentsStatus status = 6; +} + +message UserBNPLResp { + uint64 id = 1; + BNPLInfo bnpl = 2; + int32 current_step = 3; + optional float amount = 4; + optional PaymentPeriodInfo payment_period = 5; + optional bool accepted_terms = 6; + repeated BNPLPayments payments = 7; + optional string employee_id = 8; + optional auth.v1.Company company = 10; + auth.v1.InternalIAM iam = 11; + optional string updated_at = 12; + optional string created_at = 13; + Asset selected_asset = 14; + optional string rejection_reason = 15; +} + +message UserBNPLReq { + uint64 id = 1; + int64 bnpl_id = 2; + optional string created_at = 3; + optional string employee_id = 4; + optional int64 company_id = 5; + auth.v1.InternalIAM iam = 6; + optional float amount = 7; + optional PaymentPeriodInfo payment_period = 8; + optional bool has_agreed_contract = 9; + optional int32 current_step = 10; // Can be useful for admin to change the current step + optional int64 asset_id = 11; +} + +message PaymentPeriodInfo { + uint64 id = 1; + uint64 period = 2; + bool enabled = 3; +} +message BNPLInfo { + uint64 id = 1; + string description = 3; + repeated Asset supported_assets = 2; + optional bool enabled = 4; + float amount_start = 5; + float amount_end = 6; + float amount_steps = 7; + repeated PaymentPeriodInfo payment_period = 8; + repeated auth.v1.Company possible_companies = 11; + string updated_at = 12; + string created_at = 13; + string expires_at = 14; +} + +message BNPLList { + repeated BNPLInfo list = 1; + uint32 page_no = 2; + uint32 page_size = 3; + uint32 total_count = 4; +} + +/* + Transaction +*/ + +message TransactionList { + repeated Transaction list = 1; + uint32 page_no = 2; + uint32 page_size = 3; + uint32 total_count = 4; +} + +enum TransactionType { + UNKNOWN = 0; + BUY = 1; + SELL = 2; + INTERNAL_TRANSFER = 3; + EXTERNAL_TRANSFER = 4; + REDEEM = 5; + TRUST_LINE = 6; + WAGE = 7; + EXTERNAL_DEPOSIT = 8; + INTERNAL_DEPOSIT = 9; + MARKETPLACE_BUY = 10; + MARKETPLACE_SELL = 11; + LOCK = 12; + IRT_DEPOSIT = 13; + IRT_WITHDRAWAL = 14; + COMMISSION = 15; + REFERRAL_COMMISSION = 16; +} + +enum TransactionStatus { + UNDETERMINED = 0; + FAILED = -10; + SUSPENDED = -9; + CREATED = -1; + PENDING_TRX = 1; + SUCCESSFUL = 2; + PENDING_ADMIN = 3; +} + +message Transaction { + int64 id = 1; + int64 asset_id = 2; + string asset_code = 3; + optional int64 from_user_id = 4; + optional auth.v1.UserIdentityBasic from_user_info = 5; + optional int64 from_federation_id = 6; + optional Federation from_federation_info = 7; + + optional int64 to_user_id = 8; + optional auth.v1.UserIdentityBasic to_user_info = 9; + optional int64 to_federation_id = 10; + optional Federation to_federation_info = 11; + double amount = 12; + TransactionStatus status = 13; + TransactionType type = 14; + string updated_at = 15; + string created_at = 16; + string tracking_code = 17; + optional string trx_hash = 18; + optional string from_public_key = 19; + optional string to_public_key = 20; + double token_price = 21; + BalanceChange balance_change = 22; +} + +enum BalanceChange{ + NO_CHANGE = 0; + INCREASE = 1; + DECREASE = 2; +} + +message TransactionListFilter { + auth.v1.InternalIAM iam = 1; + optional uint32 page_no = 2; + optional uint32 page_size = 3; + optional int64 id = 4; + optional int64 asset_id = 5; + optional int64 from_user_id = 6; + optional int64 from_federation_id = 7; + optional int64 to_user_id = 8; + optional int64 to_federation_id = 9; + optional double amount_from = 10; + optional double amount_to = 11; + optional string tracking_code = 12; + repeated TransactionType type = 13; + repeated TransactionStatus status = 14; + optional string from_date = 15; + optional string to_date = 16; +} + +/* + Transfer +*/ + +message TransferAssetReq { + auth.v1.InternalIAM iam = 1; + auth.v1.Recipient recipient = 2; + double amount = 3; + optional int64 network_id = 4; + int64 asset_id = 5; + optional bool approval = 6; + optional auth.v1.TFA tfa = 7; +} + +message TransferAssetRes { + auth.v1.Recipient recipient = 1; + double amount = 2; + // TODO: Change to Asset + int64 transaction_id = 3; + string transaction_hash = 4; + Asset asset = 5; +} + +/* + Redeem Token; +*/ +message RedeemTokenReq { + auth.v1.InternalIAM iam = 1; + int64 asset_id = 2; + uint64 bank_info_id = 3; + double amount = 4; + optional string tfa_code = 5; +} + +message CalculateRedeemTokenRes { + Asset asset = 1; + double free_balance = 2; + double total_balance = 3; + double request_amount = 4; + double profit_capital = 5; + double user_capital = 6; + optional auth.v1.BankInfo bank_info = 7; +} + +message RedeemTokenRes { + uint64 id = 1; + int64 user_id = 2; + Asset asset = 3; + double free_balance = 4; + double total_balance = 5; + double request_amount = 6; + string created_at = 7; + bool is_paid = 8; + // receipt.Receipt receipt = 8; + double calculated_profit = 9; + optional auth.v1.BankInfo bank_info = 10; + optional string receipt = 11; +} +message RedeemTokenResList { + repeated RedeemTokenRes list = 1; + uint32 page_no = 2; + uint32 page_size = 3; + uint32 total_count = 4; +} + +/* + Utility: Get Public Key from national id +*/ + +message NationalIDReq { + auth.v1.InternalIAM iam = 1; + string national_id = 2; +} + +message PubKeyRes { + string pub_key = 1; +} + +/* + Network Details; +*/ +enum NetworkType { + UNKNOWN_NETWORK_TYPE = 0; + ETH = 1; + XLM = 2; + BTC = 3; +} + +message Network { + int64 id = 1; + string name = 2; + string code = 3; + string explorer = 4; + int64 gas_asset_id = 5; + string description = 6; + NetworkType type = 7; + bool is_active = 8; + string image = 9; + string updated_at = 10; + string created_at = 11; +} + +message NetworkList { + repeated Network list = 1; + uint32 page_no = 2; + uint32 page_size = 3; + uint32 total_count = 4; +} + +/* + * Commission + * */ + +enum CommissionType { + COMMISSION_TYPE_ICO = 0; + COMMISSION_TYPE_MARKET_MAKER = 1; + COMMISSION_TYPE_MARKET_TAKER = 2; + COMMISSION_TYPE_BNPL = 3; + COMMISSION_TYPE_REDEEM = 4; +} + +message Commission { + uint64 id = 1; + string name = 2; + double service_static = 3; + double service_percentage = 4; + double tax_static = 5; + double tax_percentage = 6; + Asset asset = 7; + CommissionType type = 8; + optional string collector = 9; + optional string description = 10; + string updated_at = 11; + string created_at = 12; +} + +message CommissionList { + repeated Commission list = 1; + uint32 page_no = 2; + uint32 page_size = 3; + uint32 total_count = 4; +} + +message EffectiveCommission { + double service = 1; + double tax = 2; + double total = 3; +} + +message RefundCommissionReq { + auth.v1.UserIdentityBasic user = 3; + uint64 commission_log_id = 1; +} +message CommissionReq { + uint64 commission_id = 1; + double amount = 2; + auth.v1.UserIdentityBasic user = 3; +} + +message CommissionRes { + uint64 commission_log_id = 1; +} + +message InitReferrerCommissionLogIn { + int64 referrer_id = 1; + int64 user_id = 2; + double amount = 3; +} + +message ReferrerCommissionLogOut { + double amount = 1; + string mobile = 2; + bool is_identity_verified = 3; + double commission_percentage = 4; +} +message ReferrerCommissionLogsList { + repeated ReferrerCommissionLogOut list = 1; + uint32 page_no = 2; + uint32 page_size = 3; + uint32 total_count = 4; +} + +message TotalReferralCommissionIn { + int64 referrer_id = 1; +} + +message TotalReferralCommissionOut { + double claimed = 1; + double unclaimed = 2; +} + +message ClaimReferralCommissionIn { + auth.v1.User user = 1; +} + +/* + * IPG - Internet Payment Gateway + * 1. Get Token + * 2. Confirm + * 3. Cancel + * 4. [optional] check balance + * */ + +// represent the information regarding the withdraw in bank +// message BalanceReq { +// auth.v1.InternalIAM iam = 1; +// auth.v1.BankInfo bank_info = 2; // BankInfo +// } + +enum AccountingType { + ACCOUNTING_TYPE_WITHDRAW = 0; + + // Deposits + ACCOUNTING_TYPE_DEPOSIT_IPG = 10; + ACCOUNTING_TYPE_DEPOSIT_BANK_ACCOUNT = 11; + ACCOUNTING_TYPE_DEPOSIT_IBAN = 12; + ACCOUNTING_TYPE_DEPOSIT_CARD = 13; + ACCOUNTING_TYPE_DEPOSIT_DIRECT_DEBIT = 14; + + // Withdraw + ACCOUNTING_TYPE_WITHDRAW_IBAN = 20; // User request to receive irt via iban + ACCOUNTING_TYPE_WITHDRAW_CARD = 21; // User request to receive irt via card no + ACCOUNTING_TYPE_WITHDRAW_BANK_ACCOUNT = 22; // User request to receive irt via bank + ACCOUNTING_TYPE_WITHDRAW_IPG_REFUND = 23; + + // ??? +} +enum AccountingStatus { + ACCOUNTING_STATUS_UNKNOWN = 0; + ACCOUNTING_STATUS_CREATED = 1; + ACCOUNTING_STATUS_PENDING = 2; + ACCOUNTING_STATUS_SUCCESS = 3; + ACCOUNTING_STATUS_FAILED = 4; + ACCOUNTING_STATUS_CANCELLED = 5; + ACCOUNTING_STATUS_REJECTED = 6; +} + +enum IPGStatus { + IPG_SUCCESS = 0; + IPG_FAILED = -1; + IPG_PENDING = 1; +} + +// represent the information regarding the sale of the token +message IPGGetTokenReq { + auth.v1.InternalIAM iam = 1; + double amount = 2; + repeated string allowed_card_numbers = 3; +} + +// represent the information regarding the ipg gateway +message IPGGetTokenRes { + string url = 1; + int64 amount = 2; +} + +message IPGConfirmReq { + string redirected_url = 1; // This field includes all of ipg's query params + // string ref_id = 1; + // string res_code = 2; + // string sale_order_id = 3; + // string sale_reference_id = 4; + // string card_holder_info = 5; + // string card_holder_pan = 6; + // string amount = 7; +} + + +message WithdrawLog { + uint64 id = 1; + Accounting accounting = 2; + string rrn = 3; + int64 amount = 4; + AccountingStatus status = 5; + string created_at = 6; + string updated_at = 7; + optional Transaction transaction = 8; + optional auth.v1.BankInfo bankinfo_id = 10; + optional bool accepted_by_admin = 11; +} + +enum PSP { + PSP_UNKNOWN = 0; + + PSP_VANDAR_BP_MELLAT = 10; + PSP_VANDAR_SEP = 11; + PSP_VANDAR = 12; + + PSP_BP_MELLAT = 20; +} + +message Accounting { + uint64 id = 1; + int64 user_id = 2; + int64 balance = 3; + auth.v1.UserIdentityBasic user = 4; +} + +message IPGGenTokenPayload { + int64 amount = 2; + string payer_id = 3; + string mobile = 4; + string national_id = 5; + int64 order_id = 6; + string callback_url = 7; + repeated string bank_cards = 8; +} + +message IPGLog { + string ref_id = 1; + Accounting accounting = 2; + int64 amount = 4; + AccountingStatus status = 5; + string created_at = 6; + string updated_at = 7; + string token = 8; + PSP psp = 9; + optional int64 transaction_id = 10; + optional Transaction transaction = 11; +} + +message IPGLogReq { + auth.v1.InternalIAM iam = 1; + string ref_id = 2; +} + +message IPGConfirmRes { + string ref_id = 1; + optional string error = 2; +} + +message SaleManualReq { + auth.v1.InternalIAM iam = 1; + int64 asset_id = 2; + double amount = 3; + string paid_at = 4; + string rrn = 5; + string national_id = 6; + optional uint64 discount_code = 7; +} + +/* IRT + * + * */ + +message DepositIRTReq { + auth.v1.InternalIAM iam = 1; + double amount = 3; +} + +message WithdrawIRTReq { + auth.v1.InternalIAM iam = 1; + double amount = 2; + int64 bank_info_id = 3; + auth.v1.TFA tfa = 4; +} + +message WithdrawIRTRes { + uint64 id = 1; + int64 amount = 2; + string transaction_hash = 3; + auth.v1.BankInfo bank_info = 4; +} + +message BuyAssetReq { + auth.v1.InternalIAM iam = 1; + int64 asset_id = 2; + double amount_irt = 3; + double amount_asset = 4; + BuyAssetSide side = 5; + optional string discount_code = 6; +} + +message DeclineBuyContractReq { + auth.v1.InternalIAM iam = 1; + uint64 agreement_id = 2; +} + +message ConfirmBuyAssetReq { + auth.v1.InternalIAM iam = 1; + uint64 agreement_id = 2; // Only in asset that require agreement contract + optional auth.v1.TFA tfa = 3; // This might be used in the future +} + +enum BuyAssetSide { + BUY_ASSET_FROM_BASE = 0; + BUY_ASSET_TO_BASE = 1; +} + +message CalcBuyAssetRes { + BuyAssetSide side = 1; + double calculated_irt_amount = 2; + double calculated_asset_amount = 3; + EffectiveCommission commission = 4; + optional AssetDiscountRes discount_detail = 5; +} + +message BuyAssetRes { + bool success = 1; + string irt_hash = 2; + string asset_hash = 3; +} + +/* Contract */ +enum ContractType { + CONTRACT_TYPE_ICO = 0; + CONTRACT_TYPE_MARKET = 1; // FIXME: Please remove this :) + CONTRACT_TYPE_BNPL = 2; + CONTRACT_TYPE_REDEEM = 3; + CONTRACT_TYPE_MARKET_MAKER = 4; + CONTRACT_TYPE_MARKET_TAKER = 5; +} + +// agreement_id +message ContractRes { + string link = 1; + uint64 agreement_id = 2; + uint64 transaction_id = 3; + string contract_hash = 4; + string contract_content = 5; +} diff --git a/wallet/v1/srv.proto b/wallet/v1/srv.proto new file mode 100644 index 0000000..00475cc --- /dev/null +++ b/wallet/v1/srv.proto @@ -0,0 +1,70 @@ +syntax = "proto3"; + +package wallet.v1; + +import "auth/v1/msg.proto"; +import "base/v1/msg.proto"; +import "wallet/v1/msg.proto"; + +service WalletService { + rpc WalletSrvHealth(base.v1.Empty) returns (base.v1.StatusRes); + + rpc GetNetworkList(base.v1.Empty) returns (NetworkList); + + rpc GetAssetList(AssetFilter) returns (AssetList); + rpc GetAsset(GetAssetReq) returns (Asset); + rpc GetAssetCommissions(base.v1.IdReq) returns (CommissionList); + rpc GetAssetPrice(base.v1.IdReq) returns (AssetPrice); + rpc AssetDiscount(AssetDiscountReq) returns (AssetDiscountRes); + + rpc UserInitWallet(UserInitWalletReq) returns (base.v1.StatusRes); + rpc UserGetWalletList(auth.v1.InternalIAM) returns (WalletList); + rpc GetBalance(BalanceReq) returns (BalanceRes); + rpc CheckBalance(CheckBalanceReq) returns (base.v1.Empty); // Throws an error if balance is not enough + + rpc UserGetTransactionList(TransactionListFilter) returns (TransactionList); + + // Commission Logs + rpc GetReferrerCommissionLogsList(auth.v1.InternalIAM) returns (ReferrerCommissionLogsList); + rpc GetTotalReferralCommission(TotalReferralCommissionIn) returns (TotalReferralCommissionOut); + rpc ClaimReferralCommission(ClaimReferralCommissionIn) returns (base.v1.StatusRes); + + // Get Token from IPG is and internal api + rpc IPGGetToken(IPGGetTokenReq) returns (IPGGetTokenRes); + // IPG Confirm is a public api + rpc IPGConfirm(IPGConfirmReq) returns (IPGConfirmRes); + rpc GetIPGLog(IPGLogReq) returns (IPGLog); + + // Admin can increase user's balance as wish + // rpc AdminManualSaleDeposit(SaleManualReq) returns (base.v1.StatusRes); + + // BNPL + rpc GetBNPLList(base.v1.Empty) returns (BNPLList); + rpc GetBNPLInfo(base.v1.IdReq) returns (BNPLInfo); + rpc GetUserBNPLInfo(GetUserBNPLInfoReq) returns (UserBNPLResp); + rpc SubmitBNPLForm(UserBNPLReq) returns (base.v1.StatusRes); + rpc UpdateBNPL(UserBNPLReq) returns (base.v1.StatusRes); + rpc CancelBNPL(auth.v1.IdReqWithIAM) returns (base.v1.StatusRes); + + // Redeem Token + rpc CalculateRedeemToken(RedeemTokenReq) returns (CalculateRedeemTokenRes); + rpc RedeemToken(RedeemTokenReq) returns (base.v1.StatusRes); + rpc RedeemTokenList(auth.v1.ReqWithIAMAndParams) returns (RedeemTokenResList); + + // Assets routing + rpc InternalTransferAsset(TransferAssetReq) returns (TransferAssetRes); + rpc ExternalTransferAsset(TransferAssetReq) returns (TransferAssetRes); + + // --- IRT --- + rpc WithdrawIRT(WithdrawIRTReq) returns (WithdrawIRTRes); + rpc DepositIRT(DepositIRTReq) returns (IPGGetTokenRes); + + // --- Buy Asset --- + rpc CalcBuyAsset(BuyAssetReq) returns (CalcBuyAssetRes); + rpc BuyAsset(ConfirmBuyAssetReq) returns (BuyAssetRes); + + // -- Contract -- + rpc GenerateBuyContract(BuyAssetReq) returns (ContractRes); + rpc DeclineBuyContract(DeclineBuyContractReq) returns (base.v1.StatusRes); + // rpc GenerateMarketContract(MarketContractReq) returns (ContractRes); +} diff --git a/wallet_message.proto b/wallet_message.proto deleted file mode 100644 index 40a7738..0000000 --- a/wallet_message.proto +++ /dev/null @@ -1,379 +0,0 @@ -syntax = "proto3"; - -package wallet; - -import "authorization_message.proto"; -import "base_message.proto"; - -/* - INTERNAL DATA -*/ - -message InternalTransactionData { - int64 transaction_id = 1; -} - -/* - Federation -*/ - -message Federation { - int64 id = 1; - int64 user_id = 2; - string ed_public = 3; - string ed_public_hash = 4; - int32 status = 5; - string created_at = 6; - string system_wallet_address = 7; -} - -message GetFederationReq { - optional int64 federation_id = 1; - optional int64 user_id = 2; - optional string ed_public = 3; - optional string ed_public_hash = 4; -} - -/* - Asset -*/ - -message AssetList { - repeated Asset list = 1; -} - -message Asset { - int64 id = 1; - string name = 2; - string code = 3; - string issuer = 4; - int32 decimal = 5; - double limit_amount = 6; - string anchor = 7; - string image = 8; - string description = 9; - string url = 10; - int64 buy_unit_price = 11; - int64 sell_unit_price = 12; - double buy_min_amount = 13; - double buy_max_amount = 14; - double sell_min_amount = 15; - double sell_max_amount = 16; - double buy_fee_amount = 17; - int64 buy_fee_price = 18; - double sell_fee_amount = 19; - int64 sell_fee_price = 20; - double withdraw_min_amount = 21; - double withdraw_max_amount = 22; - bool is_active = 23; - bool can_buy = 24; - bool can_sell = 25; - bool can_deposit = 26; - bool can_withdraw = 27; - string updated_at = 28; - string created_at = 29; - repeated string images = 30; - int32 status = 31; - AssetMeta meta = 32; -} - -message GetAssetReq { - optional int64 id = 1; - optional string code = 3; -} - -message AssetMeta { - PropertyMeta property = 1; -} - -message PropertyMeta { - string description = 1; - string builder_description = 2; - string white_paper_url = 3; - string expert_report_url = 4; - string project_catalog_url = 5; - string ownership_document_url = 6; - double total_area_meters = 7; - int32 total_unit_count = 8; - string usage_type = 9; - string completion_date = 10; - string user_agreement_url = 11; -} - -/* - BNPL - not really but close name -*/ - -// enum BNPLPgState { -// -// } - -message GetUserBNPLInfoReq { - authorization.InternalIAM iam = 1; - base.IdReq id = 2; -} - -enum BNPLPaymentsStatus { - PENDING = 0; - PAYED = 1; - OVER_DUE = 2; - NOT_STARTED = 3; - NOT_YET_DUE = 4; - CANCLED = 5; -} -message BNPLPayments { - uint64 id = 1; - double amount = 2; - double amount_irr = 7; - bool is_paied = 3; - string due_date = 4; - string settlement_date = 5; - BNPLPaymentsStatus status = 6; -} - -message UserBNPLResp { - uint64 id = 1; - BNPLInfo bnpl = 2; - int32 current_step = 3; - optional float amount = 4; - optional PaymentPeriodInfo payment_period = 5; - optional bool accepted_terms = 6; - repeated BNPLPayments payments = 7; - optional string employee_id = 8; - optional authorization.Company company = 10; - authorization.InternalIAM iam = 11; - optional string updated_at = 12; - optional string created_at = 13; - Asset selected_asset = 14; -} - -message UserBNPLReq { - uint64 id = 1; - int64 bnpl_id = 2; - authorization.InternalIAM iam = 6; - optional string created_at = 3; - optional string employee_id = 4; - optional int64 company_id = 5; - optional float amount = 7; - optional PaymentPeriodInfo payment_period = 8; - optional bool has_agreed_contract = 9; - optional int32 current_step = 10; //Can be useful for admin to change the current step - optional int64 asset_id = 11; -} - -message PaymentPeriodInfo { - uint64 id = 1; - uint64 period = 2; - bool enabled = 3; -} -message BNPLInfo { - uint64 id = 1; - string description = 3; - repeated Asset supported_assets = 2; - optional bool enabled = 4; - float amount_start = 5; - float amount_end = 6; - float amount_steps = 7; - repeated PaymentPeriodInfo payment_period = 8; - repeated authorization.Company possible_companies = 11; - string updated_at = 12; - string created_at = 13; - string expires_at = 14; -} -message BNPLList { - repeated BNPLInfo list = 1; -} - -/* - Wallet -*/ - -message WalletList { - repeated Wallet list = 1; -} - -message Wallet { - int64 id = 1; - int64 user_id = 2; - int64 asset_id = 3; - Asset asset_info = 4; - int64 federation_id = 5; - Federation federation_info = 6; - double balance = 7; - string updated_at = 8; - string created_at = 9; - string wallet_code = 10; -} - -message UserInitWalletReq { - authorization.InternalIAM iam = 1; - int64 asset_id = 2; -} - -/* - Transaction -*/ - -message TransactionList { - repeated Transaction list = 1; - int64 total_count = 2; -} - -enum TransactionType { - Unknown = 0; - Buy = 1; - Sell = 2; - Transfer = 3; - Redeem = 4; -} -enum TransactionStatus { - Undetermined = 0; - Failed = -10; - Suspended = -9; - Created = -1; - Pending = 1; - Successful = 2; -} - -message Transaction { - int64 id = 1; - int64 asset_id = 2; - // Asset asset_info = 3; //Causing network overloading - optional int64 from_user_id = 4; - optional authorization.UserIdentityBasic from_user_info = 5; - optional int64 from_federation_id = 6; - optional Federation from_federation_info = 7; - optional int64 to_user_id = 8; - optional authorization.UserIdentityBasic to_user_info = 9; - optional int64 to_federation_id = 10; - optional Federation to_federation_info = 11; - double amount = 12; - TransactionStatus status = 13; - TransactionType type = 14; - string updated_at = 15; - string created_at = 16; - string tracking_code = 17; -} - -message UserGetTransactionListReq { - authorization.InternalIAM iam = 1; - optional int32 page_index = 2; - optional int32 page_size = 3; - optional int64 id = 4; - optional int64 asset_id = 5; - optional int64 from_user_id = 6; - optional int64 from_federation_id = 7; - optional int64 to_user_id = 8; - optional int64 to_federation_id = 9; - optional double amount_from = 10; - optional double amount_to = 11; - optional TransactionStatus status = 12; - optional TransactionType type = 13; - optional string tracking_code = 14; -} -/* - Buy -*/ - -message UserBuyAssetReq { - authorization.InternalIAM iam = 1; - int64 asset_id = 2; - double amount = 3; -} - -/* - Sell -*/ - -/* - Transfer -*/ - -message UserTransferAssetReq { - authorization.InternalIAM iam = 1; - int64 asset_id = 2; - double amount = 3; - string to_wallet_address = 4; - string to_wallet_memo = 5; -} - -message UserTransferRes { - int64 transaction_id = 1; - string tracking_code = 2; -} - -// represent the information regarding the sale of the token -message SaleGetTokenReq { - authorization.InternalIAM iam = 1; - int64 asset_id = 2; - double amount = 3; -} - -// represent the information regarding the ipg gateway -message SaleGetTokenRes { - string url = 1; - int64 unit_price = 2; - int64 total_price = 3; - double amount = 4; - string asset = 5; -} - -message SaleConfirmReq { - string RefId = 1; - string ResCode = 2; - string SaleOrderId = 3; - string SaleReferenceId = 4; - string CardHolderInfo = 5; - string CardHolderPan = 6; - string FinalAmount = 7; -} - -message SaleConfirmRes { - string receiptLink = 1; -} - -message SaleManualReq { - authorization.InternalIAM iam = 1; - int64 asset_id = 2; - double amount = 3; - string paid_at = 4; - string rrn = 5; - string national_id = 6; -} - -/* - Redeem Token -*/ -message RedeemTokenReq { - authorization.InternalIAM iam = 1; - int64 asset_id = 2; - uint64 bank_info_id = 3; - double amount = 4; - optional string tfa_code = 5; -} -message CalculateRedeemTokenRes { - Asset asset = 1; - double free_balance = 2; - double total_balance = 3; - double request_amount = 4; - double profit_capital = 5; - double user_capital = 6; - optional authorization.BankInfo bank_info = 7; -} -message RedeemTokenRes { - uint64 id = 1; - int64 user_id = 2; - Asset asset = 3; - double free_balance = 4; - double total_balance = 5; - double request_amount = 6; - string created_at = 7; - bool is_paied = 8; - // receipt.Receipt receipt = 8; - double calculated_profit = 9; - optional authorization.BankInfo bank_info = 10; - optional string receipt = 11; -} -message RedeemTokenResList { - repeated RedeemTokenRes list = 1; -}