syntax = "proto3";
package provenance.marker.v1;

import "amino/amino.proto";
import "google/protobuf/any.proto";
import "cosmos_proto/cosmos.proto";
import "gogoproto/gogo.proto";
import "cosmos/base/v1beta1/coin.proto";
import "cosmos/bank/v1beta1/bank.proto";
import "cosmos/msg/v1/msg.proto";
import "ibc/applications/transfer/v1/tx.proto";
import "provenance/marker/v1/marker.proto";
import "provenance/marker/v1/accessgrant.proto";

option go_package = "github.com/provenance-io/provenance/x/marker/types";

option java_package        = "io.provenance.marker.v1";
option java_multiple_files = true;

// Msg defines the Marker Msg service.
service Msg {
  option (cosmos.msg.v1.service) = true;

  // Finalize
  rpc Finalize(MsgFinalizeRequest) returns (MsgFinalizeResponse);
  // Activate
  rpc Activate(MsgActivateRequest) returns (MsgActivateResponse);
  // Cancel
  rpc Cancel(MsgCancelRequest) returns (MsgCancelResponse);
  // Delete
  rpc Delete(MsgDeleteRequest) returns (MsgDeleteResponse);
  // Mint
  rpc Mint(MsgMintRequest) returns (MsgMintResponse);
  // Burn
  rpc Burn(MsgBurnRequest) returns (MsgBurnResponse);
  // AddAccess
  rpc AddAccess(MsgAddAccessRequest) returns (MsgAddAccessResponse);
  // DeleteAccess
  rpc DeleteAccess(MsgDeleteAccessRequest) returns (MsgDeleteAccessResponse);
  // Withdraw
  rpc Withdraw(MsgWithdrawRequest) returns (MsgWithdrawResponse);
  // AddMarker
  rpc AddMarker(MsgAddMarkerRequest) returns (MsgAddMarkerResponse);
  // Transfer marker denominated coin between accounts
  rpc Transfer(MsgTransferRequest) returns (MsgTransferResponse);
  // Transfer over ibc any marker(including restricted markers) between ibc accounts.
  // The relayer is still needed to accomplish ibc middleware relays.
  rpc IbcTransfer(MsgIbcTransferRequest) returns (MsgIbcTransferResponse);
  // Allows Denom Metadata (see bank module) to be set for the Marker's Denom
  rpc SetDenomMetadata(MsgSetDenomMetadataRequest) returns (MsgSetDenomMetadataResponse);
  // GrantAllowance grants fee allowance to the grantee on the granter's
  // account with the provided expiration time.
  rpc GrantAllowance(MsgGrantAllowanceRequest) returns (MsgGrantAllowanceResponse);
  // AddFinalizeActivateMarker
  rpc AddFinalizeActivateMarker(MsgAddFinalizeActivateMarkerRequest) returns (MsgAddFinalizeActivateMarkerResponse);
  // SupplyIncreaseProposal can only be called via gov proposal
  rpc SupplyIncreaseProposal(MsgSupplyIncreaseProposalRequest) returns (MsgSupplyIncreaseProposalResponse);
  // SupplyDecreaseProposal can only be called via gov proposal
  rpc SupplyDecreaseProposal(MsgSupplyDecreaseProposalRequest) returns (MsgSupplyDecreaseProposalResponse);
  // UpdateRequiredAttributes will only succeed if signer has transfer authority
  rpc UpdateRequiredAttributes(MsgUpdateRequiredAttributesRequest) returns (MsgUpdateRequiredAttributesResponse);
  // UpdateForcedTransfer updates the allow_forced_transfer field of a marker via governance proposal.
  rpc UpdateForcedTransfer(MsgUpdateForcedTransferRequest) returns (MsgUpdateForcedTransferResponse);
  // UpdateRequireDepositAccess updates the require_deposit_access field of a marker. Signer must have admin access or
  // be the governance module account.
  rpc UpdateRequireDepositAccess(MsgUpdateRequireDepositAccessRequest) returns (MsgUpdateRequireDepositAccessResponse);
  // SetAccountData sets the accountdata for a denom. Signer must have deposit authority.
  rpc SetAccountData(MsgSetAccountDataRequest) returns (MsgSetAccountDataResponse);
  // UpdateSendDenyList will only succeed if signer has admin authority
  rpc UpdateSendDenyList(MsgUpdateSendDenyListRequest) returns (MsgUpdateSendDenyListResponse);
  // AddNetAssetValues sets the net asset value for a marker.
  rpc AddNetAssetValues(MsgAddNetAssetValuesRequest) returns (MsgAddNetAssetValuesResponse);
  // SetAdministratorProposal sets administrators with specific access on the marker
  rpc SetAdministratorProposal(MsgSetAdministratorProposalRequest) returns (MsgSetAdministratorProposalResponse);
  // RemoveAdministratorProposal removes administrators with specific access on the marker
  rpc RemoveAdministratorProposal(MsgRemoveAdministratorProposalRequest)
      returns (MsgRemoveAdministratorProposalResponse);
  // ChangeStatusProposal is a governance proposal change marker status
  rpc ChangeStatusProposal(MsgChangeStatusProposalRequest) returns (MsgChangeStatusProposalResponse);
  // WithdrawEscrowProposal is a governance proposal to withdraw escrow coins from a marker
  rpc WithdrawEscrowProposal(MsgWithdrawEscrowProposalRequest) returns (MsgWithdrawEscrowProposalResponse);
  // SetDenomMetadataProposal is a governance proposal to set marker metadata
  rpc SetDenomMetadataProposal(MsgSetDenomMetadataProposalRequest) returns (MsgSetDenomMetadataProposalResponse);
  // UpdateParams is a governance proposal endpoint for updating the marker module's params.
  rpc UpdateParams(MsgUpdateParamsRequest) returns (MsgUpdateParamsResponse);
  // RevokeGrantAllowance revokes a fee allowance granted by a admin to a grantee.
  rpc RevokeGrantAllowance(MsgRevokeGrantAllowanceRequest) returns (MsgRevokeGrantAllowanceResponse);
}

// MsgGrantAllowanceRequest validates permission to create a fee grant based on marker admin access. If
// successful a feegrant is recorded where the marker account itself is the grantor
message MsgGrantAllowanceRequest {
  option (cosmos.msg.v1.signer) = "administrator";

  string denom         = 1;
  string administrator = 2;

  // grantee is the address of the user being granted an allowance of another user's funds.
  string grantee = 3;

  // allowance can be any of basic and filtered fee allowance (fee FeeGrant module).
  google.protobuf.Any allowance = 4 [(cosmos_proto.accepts_interface) = "FeeAllowanceI"];
}

// MsgGrantAllowanceResponse defines the Msg/GrantAllowanceResponse response type.
message MsgGrantAllowanceResponse {}

// MsgAddMarkerRequest defines the Msg/AddMarker request type.
// If being provided as a governance proposal, set the from_address to the gov module's account address.
message MsgAddMarkerRequest {
  option (cosmos.msg.v1.signer) = "from_address";

  cosmos.base.v1beta1.Coin amount                   = 1 [(gogoproto.nullable) = false];
  string                   manager                  = 3;
  string                   from_address             = 4;
  MarkerStatus             status                   = 5;
  MarkerType               marker_type              = 6;
  repeated AccessGrant     access_list              = 7 [(gogoproto.nullable) = false];
  bool                     supply_fixed             = 8;
  bool                     allow_governance_control = 9;
  bool                     allow_forced_transfer    = 10;
  repeated string          required_attributes      = 11;
  uint64                   usd_cents                = 12 [deprecated = true];
  uint64                   volume                   = 13;
  uint64                   usd_mills                = 14;
  bool                     require_deposit_access   = 15;
}

// MsgAddMarkerResponse defines the Msg/AddMarker response type
message MsgAddMarkerResponse {}

// MsgAddAccessRequest defines the Msg/AddAccess request type
message MsgAddAccessRequest {
  option (cosmos.msg.v1.signer) = "administrator";

  string               denom         = 1;
  string               administrator = 2;
  repeated AccessGrant access        = 3 [(gogoproto.nullable) = false];
}

// MsgAddAccessResponse defines the Msg/AddAccess response type
message MsgAddAccessResponse {}

// MsgDeleteAccessRequest defines the Msg/DeleteAccess request type
message MsgDeleteAccessRequest {
  option (cosmos.msg.v1.signer) = "administrator";

  string denom           = 1;
  string administrator   = 2;
  string removed_address = 3;
}
// MsgDeleteAccessResponse defines the Msg/DeleteAccess response type
message MsgDeleteAccessResponse {}

// MsgFinalizeRequest defines the Msg/Finalize request type
message MsgFinalizeRequest {
  option (cosmos.msg.v1.signer) = "administrator";

  string denom         = 1;
  string administrator = 2;
}
// MsgFinalizeResponse defines the Msg/Finalize response type
message MsgFinalizeResponse {}

// MsgActivateRequest defines the Msg/Activate request type
message MsgActivateRequest {
  option (cosmos.msg.v1.signer) = "administrator";

  string denom         = 1;
  string administrator = 2;
}
// MsgActivateResponse defines the Msg/Activate response type
message MsgActivateResponse {}

// MsgCancelRequest defines the Msg/Cancel request type
message MsgCancelRequest {
  option (cosmos.msg.v1.signer) = "administrator";

  string denom         = 1;
  string administrator = 2;
}
// MsgCancelResponse defines the Msg/Cancel response type
message MsgCancelResponse {}

// MsgDeleteRequest defines the Msg/Delete request type
message MsgDeleteRequest {
  option (cosmos.msg.v1.signer) = "administrator";

  string denom         = 1;
  string administrator = 2;
}
// MsgDeleteResponse defines the Msg/Delete response type
message MsgDeleteResponse {}

// MsgMintRequest defines the Msg/Mint request type
message MsgMintRequest {
  option (cosmos.msg.v1.signer) = "administrator";

  cosmos.base.v1beta1.Coin amount        = 1 [(gogoproto.nullable) = false];
  string                   administrator = 2;
  string                   recipient     = 3; // recipient is the optional address to receive the newly minted funds.
}
// MsgMintResponse defines the Msg/Mint response type
message MsgMintResponse {}

// MsgBurnRequest defines the Msg/Burn request type
message MsgBurnRequest {
  option (cosmos.msg.v1.signer) = "administrator";

  cosmos.base.v1beta1.Coin amount        = 1 [(gogoproto.nullable) = false];
  string                   administrator = 2;
}
// MsgBurnResponse defines the Msg/Burn response type
message MsgBurnResponse {}

// MsgWithdrawRequest defines the Msg/Withdraw request type
message MsgWithdrawRequest {
  option (cosmos.msg.v1.signer) = "administrator";

  string   denom                           = 1;
  string   administrator                   = 2;
  string   to_address                      = 3;
  repeated cosmos.base.v1beta1.Coin amount = 4 [
    (gogoproto.nullable)     = false,
    (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins",
    (amino.dont_omitempty)   = true,
    (amino.encoding)         = "legacy_coins"
  ];

  // market_id is an optional exchange market id. If non-zero, the withdrawn funds will be committed
  // to that market on behalf of the to_address after the withdrawal completes.
  uint32 market_id = 5;

  // event_tag is an optional string included in commitment events when market_id is non-zero. Max length is 100
  // characters.
  string event_tag = 6;
}

// MsgWithdrawResponse defines the Msg/Withdraw response type
message MsgWithdrawResponse {}

// MsgTransferRequest defines the Msg/Transfer request type
message MsgTransferRequest {
  option (cosmos.msg.v1.signer) = "administrator";

  cosmos.base.v1beta1.Coin amount        = 1 [(gogoproto.nullable) = false];
  string                   administrator = 3;
  string                   from_address  = 4;
  string                   to_address    = 5;
}

// MsgTransferResponse defines the Msg/Transfer response type
message MsgTransferResponse {}

// MsgIbcTransferRequest defines the Msg/IbcTransfer request type for markers.
message MsgIbcTransferRequest {
  option (cosmos.msg.v1.signer) = "administrator";

  ibc.applications.transfer.v1.MsgTransfer transfer = 1 [
    (gogoproto.nullable)   = false,
    (gogoproto.customtype) = "github.com/cosmos/ibc-go/v10/modules/apps/transfer/types.MsgTransfer"
  ];
  string administrator = 2;
}

// MsgIbcTransferResponse defines the Msg/IbcTransfer response type
message MsgIbcTransferResponse {}

// MsgSetDenomMetadataRequest defines the Msg/SetDenomMetadata request type
message MsgSetDenomMetadataRequest {
  option (cosmos.msg.v1.signer) = "administrator";

  cosmos.bank.v1beta1.Metadata metadata = 1
      [(gogoproto.nullable) = false, (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/x/bank/types.Metadata"];
  string administrator = 2;
}

// MsgSetDenomMetadataResponse defines the Msg/SetDenomMetadata response type
message MsgSetDenomMetadataResponse {}

// MsgAddFinalizeActivateMarkerRequest defines the Msg/AddFinalizeActivateMarker request type
message MsgAddFinalizeActivateMarkerRequest {
  option (cosmos.msg.v1.signer) = "from_address";

  cosmos.base.v1beta1.Coin amount                   = 1 [(gogoproto.nullable) = false];
  string                   manager                  = 3;
  string                   from_address             = 4;
  MarkerType               marker_type              = 5;
  repeated AccessGrant     access_list              = 6 [(gogoproto.nullable) = false];
  bool                     supply_fixed             = 7;
  bool                     allow_governance_control = 8;
  bool                     allow_forced_transfer    = 9;
  repeated string          required_attributes      = 10;
  uint64                   usd_cents                = 11 [deprecated = true];
  uint64                   volume                   = 12;
  uint64                   usd_mills                = 13;
  // require_deposit_access enforces deposit-access control on coins sent into this marker regardless of marker type.
  bool require_deposit_access = 14;
}

// MsgAddFinalizeActivateMarkerResponse defines the Msg/AddFinalizeActivateMarker response type
message MsgAddFinalizeActivateMarkerResponse {}

// MsgSupplyIncreaseProposalRequest defines a governance proposal to administer a marker and increase total supply of
// the marker through minting coin and placing it within the marker or assigning it directly to an account
message MsgSupplyIncreaseProposalRequest {
  option (gogoproto.equal)      = true;
  option (cosmos.msg.v1.signer) = "authority";

  cosmos.base.v1beta1.Coin amount         = 1 [(gogoproto.nullable) = false];
  string                   target_address = 2; // an optional target address for the minted coin from this request
  string                   authority = 3 [(cosmos_proto.scalar) = "cosmos.AddressString"]; // signer of the proposal
}

// MsgSupplyIncreaseProposalResponse defines the Msg/SupplyIncreaseProposal response type
message MsgSupplyIncreaseProposalResponse {}

// MsgSupplyDecreaseProposalRequest defines a governance proposal to decrease total supply of the marker
message MsgSupplyDecreaseProposalRequest {
  option (gogoproto.equal)      = true;
  option (cosmos.msg.v1.signer) = "authority";

  cosmos.base.v1beta1.Coin amount = 1
      [(gogoproto.nullable) = false, (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Coin"];
  string authority = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"]; // signer of the proposal
}

// MsgSupplyIncreaseProposalResponse defines the Msg/SupplyDecreaseProposal response type
message MsgSupplyDecreaseProposalResponse {}

// MsgUpdateRequiredAttributesRequest defines a msg to update/add/remove required attributes from a resticted marker
// signer must have transfer authority to change attributes, to update attribute add current to remove list and new to
// add list
message MsgUpdateRequiredAttributesRequest {
  option (gogoproto.equal)      = true;
  option (cosmos.msg.v1.signer) = "transfer_authority";

  // The denomination of the marker to update.
  string denom = 1;
  // List of required attributes to remove from marker.
  repeated string remove_required_attributes = 2;
  // List of required attributes to add to marker.
  repeated string add_required_attributes = 3;
  // The signer of the message.  Must have transfer authority to marker or be governance module account address.
  string transfer_authority = 4 [(cosmos_proto.scalar) = "cosmos.AddressString"];
}

// MsgUpdateRequiredAttributesResponse defines the Msg/UpdateRequiredAttributes response type
message MsgUpdateRequiredAttributesResponse {}

// MsgUpdateForcedTransferRequest defines a msg to update the allow_forced_transfer field of a marker.
// It is only usable via governance proposal.
message MsgUpdateForcedTransferRequest {
  option (gogoproto.equal)      = true;
  option (cosmos.msg.v1.signer) = "authority";

  // The denomination of the marker to update.
  string denom = 1;
  // Whether an admin can transfer restricted coins from a 3rd-party account without their signature.
  bool allow_forced_transfer = 2;
  // The signer of this message. Must be the governance module account address.
  string authority = 3 [(cosmos_proto.scalar) = "cosmos.AddressString"];
}

// MsgUpdateForcedTransferResponse defines the Msg/UpdateForcedTransfer response type
message MsgUpdateForcedTransferResponse {}

// MsgUpdateRequireDepositAccessRequest defines a msg to update the require_deposit_access field of a marker.
// Signer must have admin access on the marker or be a governance proposal.
message MsgUpdateRequireDepositAccessRequest {
  option (gogoproto.equal)      = true;
  option (cosmos.msg.v1.signer) = "signer";

  // The denomination of the marker to update.
  string denom = 1;
  // Whether deposit access is required to send coins into this marker regardless of marker type.
  bool require_deposit_access = 2;
  // The signer of this message. Must have admin access on the marker or be the governance module account address.
  string signer = 3 [(cosmos_proto.scalar) = "cosmos.AddressString"];
}

// MsgUpdateRequireDepositAccessResponse defines the Msg/UpdateRequireDepositAccess response type
message MsgUpdateRequireDepositAccessResponse {}

// MsgSetAccountDataRequest defines a msg to set/update/delete the account data for a marker.
// Signer must have deposit authority or be a gov proposal.
message MsgSetAccountDataRequest {
  option (gogoproto.equal)      = true;
  option (cosmos.msg.v1.signer) = "signer";

  // The denomination of the marker to update.
  string denom = 1;
  // The desired accountdata value.
  string value = 2;
  // The signer of this message. Must have deposit authority or be the governance module account address.
  string signer = 3 [(cosmos_proto.scalar) = "cosmos.AddressString"];
}

// MsgSetAccountDataResponse defines the Msg/SetAccountData response type
message MsgSetAccountDataResponse {}

// MsgUpdateSendDenyListRequest defines a msg to add/remove addresses to send deny list for a resticted marker
// signer must have transfer authority
message MsgUpdateSendDenyListRequest {
  option (gogoproto.equal)      = true;
  option (cosmos.msg.v1.signer) = "authority";

  // The denomination of the marker to update.
  string denom = 1;
  // List of bech32 addresses to remove from the deny send list.
  repeated string remove_denied_addresses = 2;
  // List of bech32 addresses to add to the deny send list.
  repeated string add_denied_addresses = 3;
  // The signer of the message.  Must have admin authority to marker or be governance module account address.
  string authority = 4 [(cosmos_proto.scalar) = "cosmos.AddressString"];
}

// MsgUpdateSendDenyListResponse defines the Msg/UpdateSendDenyList response type
message MsgUpdateSendDenyListResponse {}

// MsgAddNetAssetValuesRequest defines the Msg/AddNetAssetValues request type
message MsgAddNetAssetValuesRequest {
  option (cosmos.msg.v1.signer) = "administrator";

  string denom         = 1;
  string administrator = 2;
  // Net asset values to set.
  // The price can use a special "usd" denom, where 1usd = $0.001 and 1000usd = $1.000.
  repeated NetAssetValue net_asset_values = 3 [(gogoproto.nullable) = false];
}

// MsgAddNetAssetValuesResponse defines the Msg/AddNetAssetValue response type
message MsgAddNetAssetValuesResponse {}

// MsgSetAdministratorProposalRequest defines the Msg/SetAdministratorProposal request type
message MsgSetAdministratorProposalRequest {
  option (gogoproto.equal)      = true;
  option (cosmos.msg.v1.signer) = "authority";

  string               denom  = 1;
  repeated AccessGrant access = 2 [(gogoproto.nullable) = false];
  // The signer of the message.  Must have admin authority to marker or be governance module account address.
  string authority = 3 [(cosmos_proto.scalar) = "cosmos.AddressString"];
}

// MsgSetAdministratorProposalResponse defines the Msg/SetAdministratorProposal response type
message MsgSetAdministratorProposalResponse {}

// MsgRemoveAdministratorProposalRequest defines the Msg/RemoveAdministratorProposal request type
message MsgRemoveAdministratorProposalRequest {
  option (gogoproto.equal)      = true;
  option (cosmos.msg.v1.signer) = "authority";

  string          denom           = 1;
  repeated string removed_address = 2;
  // The signer of the message.  Must have admin authority to marker or be governance module account address.
  string authority = 3 [(cosmos_proto.scalar) = "cosmos.AddressString"];
}

// MsgRemoveAdministratorProposalResponse defines the Msg/RemoveAdministratorProposal response type
message MsgRemoveAdministratorProposalResponse {}

// MsgChangeStatusProposalRequest defines the Msg/ChangeStatusProposal request type
message MsgChangeStatusProposalRequest {
  option (gogoproto.equal)      = true;
  option (cosmos.msg.v1.signer) = "authority";

  string       denom      = 1;
  MarkerStatus new_status = 2;
  // The signer of the message.  Must have admin authority to marker or be governance module account address.
  string authority = 3 [(cosmos_proto.scalar) = "cosmos.AddressString"];
}

// MsgChangeStatusProposalResponse defines the Msg/ChangeStatusProposal response type
message MsgChangeStatusProposalResponse {}

// MsgWithdrawEscrowProposalRequest defines the Msg/WithdrawEscrowProposal request type
message MsgWithdrawEscrowProposalRequest {
  option (gogoproto.equal)      = true;
  option (cosmos.msg.v1.signer) = "authority";

  string   denom                           = 1;
  repeated cosmos.base.v1beta1.Coin amount = 2
      [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"];
  string target_address = 3;
  // The signer of the message.  Must have admin authority to marker or be governance module account address.
  string authority = 4 [(cosmos_proto.scalar) = "cosmos.AddressString"];
}

// MsgWithdrawEscrowProposalResponse defines the Msg/WithdrawEscrowProposal response type
message MsgWithdrawEscrowProposalResponse {}

// MsgSetDenomMetadataProposalRequest defines the Msg/SetDenomMetadataProposal request type
message MsgSetDenomMetadataProposalRequest {
  option (cosmos.msg.v1.signer) = "authority";

  cosmos.bank.v1beta1.Metadata metadata = 1
      [(gogoproto.nullable) = false, (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/x/bank/types.Metadata"];
  // The signer of the message.  Must have admin authority to marker or be governance module account address.
  string authority = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"];
}

// MsgSetDenomMetadataProposalResponse defines the Msg/SetDenomMetadataProposal response type
message MsgSetDenomMetadataProposalResponse {}

// MsgUpdateParamsRequest is a request message for the UpdateParams endpoint.
message MsgUpdateParamsRequest {
  option (cosmos.msg.v1.signer) = "authority";

  // authority should be the governance module account address.
  string authority = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];

  // params are the new param values to set.
  Params params = 2 [(gogoproto.nullable) = false];
}

// MsgUpdateParamsResponse is a response message for the UpdateParams endpoint.
message MsgUpdateParamsResponse {}

// MsgRevokeGrantAllowanceRequest is a request message for the RevokeFeeGrantAllowance endpoint.
message MsgRevokeGrantAllowanceRequest {
  option (cosmos.msg.v1.signer) = "administrator";

  string denom         = 1;
  string administrator = 2;

  // address of the grantee whose allowance is being revoked.
  string grantee = 3;
}

// MsgRevokeGrantResponse is a response message for the RevokeFeeGrantAllowance endpoint.
message MsgRevokeGrantAllowanceResponse {}