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

import "gogoproto/gogo.proto";
import "cosmos/auth/v1beta1/auth.proto";
import "cosmos_proto/cosmos.proto";
import "cosmos/base/v1beta1/coin.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;

// Params defines the set of params for the account module.
message Params {
  option (gogoproto.equal) = true;
  // Deprecated: Prefer to use `max_supply` instead. Maximum amount of supply to allow a marker to be created with
  uint64 max_total_supply = 1 [deprecated = true];
  // indicates if governance based controls of markers is allowed.
  bool enable_governance = 2;
  // a regular expression used to validate marker denom values from normal create requests (governance
  // requests are only subject to platform coin validation denom expression)
  string unrestricted_denom_regex = 3;
  // maximum amount of supply to allow a marker to be created with
  string max_supply = 4 [(gogoproto.customtype) = "cosmossdk.io/math.Int", (gogoproto.nullable) = false];
}

// MarkerAccount holds the marker configuration information in addition to a base account structure.
message MarkerAccount {
  option (gogoproto.goproto_getters)         = false;
  option (gogoproto.goproto_stringer)        = false;
  option (cosmos_proto.implements_interface) = "MarkerAccountI";

  // base cosmos account information including address and coin holdings.
  cosmos.auth.v1beta1.BaseAccount base_account = 1 [(gogoproto.embed) = true];
  // Address that owns the marker configuration.  This account must sign any requests
  // to change marker config (only valid for statuses prior to finalization)
  string manager = 2;
  // Access control lists
  repeated AccessGrant access_control = 3 [(gogoproto.nullable) = false];
  // Indicates the current status of this marker record.
  MarkerStatus status = 4;
  // value denomination and total supply for the token.
  string denom = 5;
  // the total supply expected for a marker.  This is the amount that is minted when a marker is created.
  // Note: This is a static configuration value, not the current circulating supply.
  // To query the current circulating supply, use the bank module's SupplyOf query.
  string supply = 6 [(gogoproto.customtype) = "cosmossdk.io/math.Int", (gogoproto.nullable) = false];
  // Marker type information
  MarkerType marker_type = 7;
  // A fixed supply will mint additional coin automatically if the total supply decreases below a set value.  This
  // may occur if the coin is burned or an account holding the coin is slashed. (default: true)
  bool supply_fixed = 8;
  // indicates that governance based control is allowed for this marker
  bool allow_governance_control = 9;
  // Whether an admin can transfer restricted coins from a 3rd-party account without their signature.
  bool allow_forced_transfer = 10;
  // list of required attributes on restricted marker in order to send and receive transfers if sender does not have
  // transfer authority
  repeated string required_attributes = 11;
  // requires that an address have deposit access in order to send coins into this marker account, regardless of marker
  // type. When false (default), only restricted markers enforce deposit access.
  bool require_deposit_access = 12;
}

// MarkerType defines the types of marker
enum MarkerType {
  // MARKER_TYPE_UNSPECIFIED is an invalid/unknown marker type.
  MARKER_TYPE_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "Unknown"];
  // MARKER_TYPE_COIN is a marker that represents a standard fungible coin (default).
  MARKER_TYPE_COIN = 1 [(gogoproto.enumvalue_customname) = "Coin"];
  // MARKER_TYPE_RESTRICTED is a marker that represents a denom with send_enabled = false.
  MARKER_TYPE_RESTRICTED = 2 [(gogoproto.enumvalue_customname) = "RestrictedCoin"];
}

// MarkerStatus defines the various states a marker account can be in.
enum MarkerStatus {
  option (gogoproto.goproto_enum_prefix)   = false;
  option (gogoproto.goproto_enum_stringer) = false;

  // MARKER_STATUS_UNSPECIFIED - Unknown/Invalid Marker Status
  MARKER_STATUS_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "StatusUndefined"];
  // MARKER_STATUS_PROPOSED - Initial configuration period, updates allowed, token supply not created.
  MARKER_STATUS_PROPOSED = 1 [(gogoproto.enumvalue_customname) = "StatusProposed"];
  // MARKER_STATUS_FINALIZED - Configuration finalized, ready for supply creation
  MARKER_STATUS_FINALIZED = 2 [(gogoproto.enumvalue_customname) = "StatusFinalized"];
  // MARKER_STATUS_ACTIVE - Supply is created, rules are in force.
  MARKER_STATUS_ACTIVE = 3 [(gogoproto.enumvalue_customname) = "StatusActive"];
  // MARKER_STATUS_CANCELLED - Marker has been cancelled, pending destroy
  MARKER_STATUS_CANCELLED = 4 [(gogoproto.enumvalue_customname) = "StatusCancelled"];
  // MARKER_STATUS_DESTROYED - Marker supply has all been recalled, marker is considered destroyed and no further
  // actions allowed.
  MARKER_STATUS_DESTROYED = 5 [(gogoproto.enumvalue_customname) = "StatusDestroyed"];
}

// NetAssetValue defines a marker's net asset value
message NetAssetValue {
  // price is the complete value of the asset's volume
  cosmos.base.v1beta1.Coin price = 1 [(gogoproto.nullable) = false];
  // volume is the number of tokens of the marker that were purchased for the price
  uint64 volume = 2;
  // updated_block_height is the block height of last update
  uint64 updated_block_height = 3;
}

// EventMarkerAdd event emitted when marker is added
message EventMarkerAdd {
  string denom       = 1;
  string amount      = 2;
  string status      = 3;
  string manager     = 4;
  string marker_type = 5;
  string address     = 6;
}

// EventMarkerAddAccess event emitted when marker access is added
message EventMarkerAddAccess {
  EventMarkerAccess access        = 1 [(gogoproto.nullable) = false];
  string            denom         = 2;
  string            administrator = 3;
}

// EventMarkerAccess event access permissions for address
message EventMarkerAccess {
  string          address     = 1;
  repeated string permissions = 2;
}

// EventMarkerDeleteAccess event emitted when marker access is revoked
message EventMarkerDeleteAccess {
  string remove_address = 1;
  string denom          = 2;
  string administrator  = 3;
}

// EventMarkerFinalize event emitted when marker is finalized
message EventMarkerFinalize {
  string denom         = 1;
  string administrator = 2;
}

// EventMarkerActivate event emitted when marker is activated
message EventMarkerActivate {
  string denom         = 1;
  string administrator = 2;
}

// EventMarkerCancel event emitted when marker is cancelled
message EventMarkerCancel {
  string denom         = 1;
  string administrator = 2;
}

// EventMarkerDelete event emitted when marker is deleted
message EventMarkerDelete {
  string denom         = 1;
  string administrator = 2;
}

// EventMarkerMint event emitted when additional marker supply is minted
message EventMarkerMint {
  string amount        = 1;
  string denom         = 2;
  string administrator = 3;
}

// EventMarkerBurn event emitted when coin is burned from marker
message EventMarkerBurn {
  string amount        = 1;
  string denom         = 2;
  string administrator = 3;
}

// EventMarkerWithdraw event emitted when coins are withdrew from marker
message EventMarkerWithdraw {
  string coins         = 1;
  string denom         = 2;
  string administrator = 3;
  string to_address    = 4;
}

// EventMarkerTransfer event emitted when coins are transfered to from account to another
message EventMarkerTransfer {
  string amount        = 1;
  string denom         = 2;
  string administrator = 3;
  string to_address    = 4;
  string from_address  = 5;
}

// EventMarkerSetDenomMetadata event emitted when metadata is set on marker with denom
message EventMarkerSetDenomMetadata {
  string                  metadata_base        = 1;
  string                  metadata_description = 2;
  string                  metadata_display     = 3;
  repeated EventDenomUnit metadata_denom_units = 4;
  string                  administrator        = 5;
  string                  metadata_name        = 6;
  string                  metadata_symbol      = 7;
}

// EventDenomUnit denom units for set denom metadata event
message EventDenomUnit {
  string          denom    = 1;
  string          exponent = 2;
  repeated string aliases  = 3;
}

// EventSetNetAssetValue event emitted when Net Asset Value for marker is update or added
message EventSetNetAssetValue {
  string denom  = 1;
  string price  = 2;
  string volume = 3;
  string source = 4;
}

// EventMarkerParamsUpdated event emitted when marker params are updated.
message EventMarkerParamsUpdated {
  string enable_governance        = 1;
  string unrestricted_denom_regex = 2;
  string max_supply               = 3;
}