diff --git a/buf.yaml b/buf.yaml index 86367be3..980b97ec 100644 --- a/buf.yaml +++ b/buf.yaml @@ -8,6 +8,7 @@ lint: ignore_only: RPC_REQUEST_STANDARD_NAME: - proto/cmp/services/notification/v1/notify.proto + - proto/cmp/services/notification/v2/notify.proto rpc_allow_google_protobuf_empty_responses: true breaking: use: diff --git a/proto/cmp/services/cancellation/v1/accept.proto b/proto/cmp/services/cancellation/v1/accept.proto new file mode 100644 index 00000000..8e6488a3 --- /dev/null +++ b/proto/cmp/services/cancellation/v1/accept.proto @@ -0,0 +1,31 @@ +syntax = "proto3"; + +package cmp.services.cancellation.v1; + +import "cmp/types/v1/common.proto"; +import "cmp/types/v2/price.proto"; + +// Request for cancellation acceptance +// +// ![Diagram](https://storage.googleapis.com/docs-cmp-files/diagrams/proto/cmp/services/cancellation/v1/accept.proto.dot.xs.svg) +// +// [Open Message Diagram](https://storage.googleapis.com/docs-cmp-files/diagrams/proto/cmp/services/cancellation/v1/accept.proto.dot.svg) +message AcceptCancellationRequest { + // Request header + cmp.types.v1.RequestHeader header = 1; + + // Cancellation token ID + uint64 token_id = 2; + + // Refund amount to validate the acceptance on-chain + cmp.types.v2.Price refund_amount = 3; +} + +// Response for cancellation acceptance +message AcceptCancellationResponse { + // Response header + cmp.types.v1.ResponseHeader header = 1; + + // Accept cancellation transaction ID + string transaction_id = 2; +} diff --git a/proto/cmp/services/cancellation/v1/accept_counter.proto b/proto/cmp/services/cancellation/v1/accept_counter.proto new file mode 100644 index 00000000..9464a781 --- /dev/null +++ b/proto/cmp/services/cancellation/v1/accept_counter.proto @@ -0,0 +1,27 @@ +syntax = "proto3"; + +package cmp.services.cancellation.v1; + +import "cmp/types/v1/common.proto"; +import "cmp/types/v2/price.proto"; + +// Request for counter cancellation acceptance +message AcceptCounterCancellationRequest { + // Request header + cmp.types.v1.RequestHeader header = 1; + + // Cancellation token ID + uint64 token_id = 2; + + // Refund amount to validate the acceptance on-chain + cmp.types.v2.Price refund_amount = 3; +} + +// Response for counter cancellation acceptance +message AcceptCounterCancellationResponse { + // Response header + cmp.types.v1.ResponseHeader header = 1; + + // Accept counter cancellation transaction ID + string transaction_id = 2; +} diff --git a/proto/cmp/services/cancellation/v1/cancel_proposal.proto b/proto/cmp/services/cancellation/v1/cancel_proposal.proto new file mode 100644 index 00000000..8ca81a2c --- /dev/null +++ b/proto/cmp/services/cancellation/v1/cancel_proposal.proto @@ -0,0 +1,23 @@ +syntax = "proto3"; + +package cmp.services.cancellation.v1; + +import "cmp/types/v1/common.proto"; + +// Request for cancelling an active cancellation proposal +message CancelCancellationRequest { + // Request header + cmp.types.v1.RequestHeader header = 1; + + // Cancellation token ID + uint64 token_id = 2; +} + +// Response for cancelling an active cancellation proposal +message CancelCancellationResponse { + // Response header + cmp.types.v1.ResponseHeader header = 1; + + // Accept cancellation transaction ID + string transaction_id = 2; +} diff --git a/proto/cmp/services/cancellation/v1/check.proto b/proto/cmp/services/cancellation/v1/check.proto new file mode 100644 index 00000000..9f8c0848 --- /dev/null +++ b/proto/cmp/services/cancellation/v1/check.proto @@ -0,0 +1,58 @@ +syntax = "proto3"; + +package cmp.services.cancellation.v1; + +import "cmp/services/cancellation/v1/reject.proto"; +import "cmp/types/v1/common.proto"; +import "cmp/types/v2/price.proto"; +import "google/protobuf/timestamp.proto"; + +// Service for checking cancellation +// +// ![Diagram](https://storage.googleapis.com/docs-cmp-files/diagrams/proto/cmp/services/cancellation/v1/check.proto.dot.xs.svg) +// +// [Open Message Diagram](https://storage.googleapis.com/docs-cmp-files/diagrams/proto/cmp/services/cancellation/v1/check.proto.dot.svg) +service CheckCancellationService { + rpc CheckCancellation(CheckCancellationRequest) returns (CheckCancellationResponse); +} + +message CheckCancellationRequest { + // The request header + cmp.types.v1.RequestHeader header = 1; + + // The token id of the booking to be cancelled + uint64 token_id = 2; + + // The amount to be refunded + cmp.types.v2.Price refund_amount = 3; +} + +message CheckCancellationResponse { + // The response header + cmp.types.v1.ResponseHeader header = 1; + + // The token id of the booking to be cancelled + uint64 token_id = 2; + + // The amount to be refunded + cmp.types.v2.Price refund_amount = 3; + + // The policy id applied + string policy_id_applied = 4; + + // Status of the cancellation check + cmp.services.cancellation.v1.CancellationCheckStatus status = 5; + + // Rejection reason + cmp.services.cancellation.v1.CancellationRejectionReason rejection_reason = 6; + + // Cancellation check timestamp + google.protobuf.Timestamp timestamp = 7; +} + +enum CancellationCheckStatus { + CANCELLATION_CHECK_STATUS_UNSPECIFIED = 0; + CANCELLATION_CHECK_STATUS_ALREADY_CANCELLED = 1; + CANCELLATION_CHECK_STATUS_CONFIRM = 2; + CANCELLATION_CHECK_STATUS_REJECT = 3; +} diff --git a/proto/cmp/services/cancellation/v1/counter.proto b/proto/cmp/services/cancellation/v1/counter.proto new file mode 100644 index 00000000..01af2be2 --- /dev/null +++ b/proto/cmp/services/cancellation/v1/counter.proto @@ -0,0 +1,27 @@ +syntax = "proto3"; + +package cmp.services.cancellation.v1; + +import "cmp/types/v1/common.proto"; +import "cmp/types/v2/price.proto"; + +// Request for countering a cancellation +message CounterCancellationRequest { + // Request header + cmp.types.v1.RequestHeader header = 1; + + // Cancellation token ID + uint64 token_id = 2; + + // Refund amount to counter the cancellation proposal with + cmp.types.v2.Price refund_amount = 3; +} + +// Response for countering a cancellation +message CounterCancellationResponse { + // Response header + cmp.types.v1.ResponseHeader header = 1; + + // Counter cancellation transaction ID + string transaction_id = 2; +} diff --git a/proto/cmp/services/cancellation/v1/initiate.proto b/proto/cmp/services/cancellation/v1/initiate.proto new file mode 100644 index 00000000..3e0a059e --- /dev/null +++ b/proto/cmp/services/cancellation/v1/initiate.proto @@ -0,0 +1,25 @@ +syntax = "proto3"; + +package cmp.services.cancellation.v1; + +import "cmp/types/v1/common.proto"; +import "cmp/types/v2/price.proto"; + +message InitiateCancellationRequest { + // The request header + cmp.types.v1.RequestHeader header = 1; + + // The token id of the booking to be cancelled + uint64 token_id = 2; + + // The amount to be refunded + cmp.types.v2.Price refund_amount = 3; +} + +message InitiateCancellationResponse { + // The response header + cmp.types.v1.ResponseHeader header = 1; + + // Transaction id for the initiate cancellation request + string transaction_id = 2; +} diff --git a/proto/cmp/services/cancellation/v1/reject.proto b/proto/cmp/services/cancellation/v1/reject.proto new file mode 100644 index 00000000..cbf6a833 --- /dev/null +++ b/proto/cmp/services/cancellation/v1/reject.proto @@ -0,0 +1,39 @@ +syntax = "proto3"; + +package cmp.services.cancellation.v1; + +import "cmp/types/v1/common.proto"; + +// Request for cancellation rejection +message RejectCancellationRequest { + // Request Header + cmp.types.v1.RequestHeader header = 1; + + // Token ID to reject the cancellation for (Booking Token) + uint64 token_id = 2; + + // Reason for rejection + cmp.services.cancellation.v1.CancellationRejectionReason reason = 3; +} + +// Response for cancellation rejection +message RejectCancellationResponse { + // Response Header + cmp.types.v1.ResponseHeader header = 1; + + // Transaction id for the rejected cancellation + string transaction_id = 2; +} + +enum CancellationRejectionReason { + CANCELLATION_REJECTION_REASON_UNSPECIFIED = 0; + CANCELLATION_REJECTION_REASON_TECHNICAL_ERROR = 1; + CANCELLATION_REJECTION_REASON_INVALID_SERVICE_OR_BOOKING_REFERENCE = 2; + CANCELLATION_REJECTION_REASON_BOOKING_IS_ALREADY_CANCELLED = 3; + CANCELLATION_REJECTION_REASON_SERVICE_HAS_STARTED_OR_HAS_BEEN_DELIVERED = 4; + CANCELLATION_REJECTION_REASON_CANCELLATION_WINDOW_EXPIRED = 5; + CANCELLATION_REJECTION_REASON_SERVICE_CANNOT_BE_CANCELLED_ONLINE = 6; + CANCELLATION_REJECTION_REASON_RATE_OR_FARE_CANNOT_BE_CANCELLED = 7; + CANCELLATION_REJECTION_REASON_ENTIRE_PACKAGE_MUST_BE_CANCELLED = 8; // Service forms part of a package, the entire package must be cancelled + CANCELLATION_REJECTION_REASON_REFUND_CURRENCY_NOT_SUPPORTED = 9; +} diff --git a/proto/cmp/services/cancellation/v1/services.proto b/proto/cmp/services/cancellation/v1/services.proto new file mode 100644 index 00000000..a5f13252 --- /dev/null +++ b/proto/cmp/services/cancellation/v1/services.proto @@ -0,0 +1,45 @@ +syntax = "proto3"; + +// ## Cancellation Services +// +// The Cancellation services are used for any message type or vertical. +// There is an imperative workflow, which has the purpose to register the +// cancellation request moment, followed by both parties agreeing the cancellation +// is possible and the refund amount on the blockchain, so that there will be no +// disputes after a cancellation is executed. +// +// There is a detailed explanation on [Camino Docs](https://docs.camino.network/camino-messenger/cancellation) + +package cmp.services.cancellation.v1; + +import "cmp/services/cancellation/v1/accept.proto"; +import "cmp/services/cancellation/v1/accept_counter.proto"; +import "cmp/services/cancellation/v1/cancel_proposal.proto"; +import "cmp/services/cancellation/v1/counter.proto"; +import "cmp/services/cancellation/v1/initiate.proto"; +import "cmp/services/cancellation/v1/reject.proto"; + +// Cancellation service +// +// ![Diagram](https://storage.googleapis.com/docs-cmp-files/diagrams/proto/cmp/services/cancellation/v1/services.proto.dot.xs.svg) +// +// [Open Message Diagram](https://storage.googleapis.com/docs-cmp-files/diagrams/proto/cmp/services/cancellation/v1/services.proto.dot.svg) +service CancellationService { + // Initiate cancellation + rpc InitiateCancellation(InitiateCancellationRequest) returns (InitiateCancellationResponse) {} + + // Accept cancellation + rpc AcceptCancellation(AcceptCancellationRequest) returns (AcceptCancellationResponse) {} + + // Reject cancellation + rpc RejectCancellation(RejectCancellationRequest) returns (RejectCancellationResponse) {} + + // Counter cancellation + rpc CounterCancellation(CounterCancellationRequest) returns (CounterCancellationResponse) {} + + // Accept countered cancellation + rpc AcceptCounterCancellation(AcceptCounterCancellationRequest) returns (AcceptCounterCancellationResponse) {} + + // Cancel cancellation proposal + rpc CancelCancellation(CancelCancellationRequest) returns (CancelCancellationResponse) {} +} diff --git a/proto/cmp/services/notification/v1/notify.proto b/proto/cmp/services/notification/v1/notify.proto index 6b75a7cb..27045c0a 100644 --- a/proto/cmp/services/notification/v1/notify.proto +++ b/proto/cmp/services/notification/v1/notify.proto @@ -16,6 +16,11 @@ message TokenExpired { cmp.types.v1.UUID mint_id = 2; } +// Notification service for different events that the partner should be notified about +// +// ![Diagram](https://storage.googleapis.com/docs-cmp-files/diagrams/proto/cmp/services/notification/v1/notify.proto.dot.xs.svg) +// +// [Open Message Diagram](https://storage.googleapis.com/docs-cmp-files/diagrams/proto/cmp/services/notification/v1/notify.proto.dot.svg) service NotificationService { rpc TokenBoughtNotification(TokenBought) returns (google.protobuf.Empty); rpc TokenExpiredNotification(TokenExpired) returns (google.protobuf.Empty); diff --git a/proto/cmp/services/notification/v2/notify.proto b/proto/cmp/services/notification/v2/notify.proto new file mode 100644 index 00000000..3364dda7 --- /dev/null +++ b/proto/cmp/services/notification/v2/notify.proto @@ -0,0 +1,81 @@ +syntax = "proto3"; + +package cmp.services.notification.v2; + +import "cmp/services/cancellation/v1/reject.proto"; +import "cmp/types/v1/uuid.proto"; +import "google/protobuf/empty.proto"; + +// Notification service for different events that the partner should be notified about +// +// ![Diagram](https://storage.googleapis.com/docs-cmp-files/diagrams/proto/cmp/services/notification/v2/notify.proto.dot.xs.svg) +// +// [Open Message Diagram](https://storage.googleapis.com/docs-cmp-files/diagrams/proto/cmp/services/notification/v2/notify.proto.dot.svg) +service NotificationService { + rpc TokenBoughtNotification(TokenBought) returns (google.protobuf.Empty); + rpc TokenExpiredNotification(TokenExpired) returns (google.protobuf.Empty); + rpc CancellationPendingNotification(CancellationPending) returns (google.protobuf.Empty); + rpc CancellationAcceptedNotification(CancellationAccepted) returns (google.protobuf.Empty); + rpc CancellationProposalAcceptedByTheOwnerNotification(CancellationProposalAcceptedByTheOwner) returns (google.protobuf.Empty); + rpc CancellationCounteredNotification(CancellationCountered) returns (google.protobuf.Empty); + rpc CancellationProposalCancelledNotification(CancellationProposalCancelled) returns (google.protobuf.Empty); + rpc CancellationRejectedNotification(CancellationRejected) returns (google.protobuf.Empty); +} + +message TokenBought { + uint64 token_id = 1; + string tx_id = 2; + cmp.types.v1.UUID mint_id = 3; +} + +message TokenExpired { + uint64 token_id = 1; + cmp.types.v1.UUID mint_id = 2; +} + +// event CancellationPending(uint256 indexed tokenId, address indexed proposedBy, uint256 refundAmount); +message CancellationPending { + uint64 token_id = 1; + string proposed_by = 2; + uint64 refund_amount = 3; + string tx_id = 4; +} + +// event CancellationAccepted(uint256 indexed tokenId, address indexed acceptedBy, uint256 refundAmount); +message CancellationAccepted { + uint64 token_id = 1; + string accepted_by = 2; + uint64 refund_amount = 3; + string tx_id = 4; +} + +// event CancellationProposalAcceptedByTheOwner(uint256 indexed tokenId, address indexed acceptedBy, uint256 refundAmount); +message CancellationProposalAcceptedByTheOwner { + uint64 token_id = 1; + string accepted_by = 2; + uint64 refund_amount = 3; + string tx_id = 4; +} + +// event CancellationCountered(uint256 indexed tokenId, address indexed counteredBy, uint256 newRefundAmount); +message CancellationCountered { + uint64 token_id = 1; + string countered_by = 2; + uint64 new_refund_amount = 3; + string tx_id = 4; +} + +// event CancellationProposalCancelled(uint256 indexed tokenId, address indexed cancelledBy); +message CancellationProposalCancelled { + uint64 token_id = 1; + string cancelled_by = 2; + string tx_id = 3; +} + +// event CancellationRejected(uint256 indexed tokenId, address indexed rejectedBy, CancellationRejectionReason reason); +message CancellationRejected { + uint64 token_id = 1; + string rejected_by = 2; + cmp.services.cancellation.v1.CancellationRejectionReason reason = 3; + string tx_id = 4; +}