syntax = "proto3";

package utxorpc.v1beta.cardano;

// Purpose of the redeemer in a transaction.
enum RedeemerPurpose {
  REDEEMER_PURPOSE_UNSPECIFIED = 0;
  REDEEMER_PURPOSE_SPEND = 1;
  REDEEMER_PURPOSE_MINT = 2;
  REDEEMER_PURPOSE_CERT = 3;
  REDEEMER_PURPOSE_REWARD = 4;
  REDEEMER_PURPOSE_VOTE = 5;
  REDEEMER_PURPOSE_PROPOSE = 6;
}

// Redeemer information for a Plutus script.
message Redeemer {
  RedeemerPurpose purpose = 1; // Purpose of the redeemer.
  PlutusData payload = 2; // Plutus data associated with the redeemer.
  uint32 index = 3; // Index of the redeemer.
  ExUnits ex_units = 4; // Execution units consumed by the redeemer.
  bytes original_cbor = 5; // Original cbor-encoded data as seen on-chain
}

// Represents a transaction input in the Cardano blockchain.
message TxInput {
  bytes tx_hash = 1; // Hash of the previous transaction.
  uint32 output_index = 2; // Index of the output in the previous transaction.
  TxOutput as_output = 3; // Content of the input represented as output of the related transaction
  optional Redeemer redeemer = 4; // Redeemer for the Plutus script.
}

// Represents a transaction output in the Cardano blockchain.
message TxOutput {
  bytes address = 1; // Address receiving the output.
  BigInt coin = 2; // Amount of ADA in the output.
  repeated Multiasset assets = 3; // Additional native (non-ADA) assets in the output.
  optional Datum datum = 4; // Plutus data associated with the output.
  optional Script script = 5; // Script associated with the output.
}

message Datum {
  bytes hash = 1; // Hash of this datum as seen on-chain
  optional PlutusData payload = 2; // Parsed Plutus data payload
  optional bytes original_cbor = 3; // Original cbor-encoded data as seen on-chain
}

// Represents a custom asset in the Cardano blockchain.
message Asset {
  bytes name = 1; // Name of the custom asset.
  BigInt quantity = 2; // Quantity of the custom asset. This can be negative only if it is in a `Tx.mint` field and the transaction is burning tokens.
}

// Represents a multi-asset group in the Cardano blockchain.
message Multiasset {
  bytes policy_id = 1; // Policy ID governing the custom assets.
  repeated Asset assets = 2; // List of custom assets.
}

// Represents the validity interval of a transaction.
message TxValidity {
  uint64 start = 1; // Start of the validity interval.
  uint64 ttl = 2; // End of the validity interval (TTL: Time to Live).
}

// Represents the collateral information for a transaction.
message Collateral {
  repeated TxInput collateral = 1; // Collateral inputs for the transaction.
  TxOutput collateral_return = 2; // Collateral return in case of script failure.
  BigInt total_collateral = 3; // Total amount of collateral.
}

// Represents a withdrawal from a reward account.
message Withdrawal {
  bytes reward_account = 1; // Address of the reward account.
  BigInt coin = 2; // Amount of ADA withdrawn.
  Redeemer redeemer = 3; // Redeemer for the Plutus script.
}

// Represents a set of witnesses that validate a transaction
message WitnessSet {
  repeated VKeyWitness vkeywitness = 1; // List of VKey witnesses.
  repeated Script script = 2; // List of scripts.
  repeated PlutusData plutus_datums = 3; // List of Plutus data elements associated with the transaction.
  repeated Redeemer redeemers = 4; // List of redeemers
  repeated BootstrapWitness bootstrapWitnesses = 5; // List of bootstrap witnesses
}

// Auxiliary data not directly tied to the validation process
message AuxData {
  repeated Metadata metadata = 1; // List of auxiliary metadata elements.
  repeated Script scripts = 2; // List of auxiliary scripts.
}

// Represents a transaction in the Cardano blockchain.
message Tx {
  repeated TxInput inputs = 1; // List of transaction inputs
  repeated TxOutput outputs = 2; // List of transaction outputs
  repeated Certificate certificates = 3; // List of certificates
  repeated Withdrawal withdrawals = 4; // List of withdrawals
  repeated Multiasset mint = 5; // List of minted custom assets
  repeated TxInput reference_inputs = 6; // List of reference inputs
  WitnessSet witnesses = 7; // Witnesses that validte the transaction
  Collateral collateral = 8; // Collateral details in case of failed transaction
  BigInt fee = 9; // Transaction fee in ADA
  TxValidity validity = 10; // Validity interval of the transaction
  bool successful = 11; // Flag indicating whether the transaction was successful
  AuxData auxiliary = 12; // Auxiliary data not directly tied to the validation process
  bytes hash = 13; // Hash of the transaction that serves as main identifier
  repeated GovernanceActionProposal proposals = 14; // List of governance actions proposed
}

// Define a governance action proposal
message GovernanceActionProposal {
  BigInt deposit = 1; // The amount deposited for the governance action
  bytes reward_account = 2; // The reward account the deposit should be returned to
  GovernanceAction gov_action = 3;
  Anchor anchor = 4;
}

// Define a Governance Action
message GovernanceAction {
  oneof governance_action {
    ParameterChangeAction parameter_change_action = 1; // Change on-chain parameters
    HardForkInitiationAction hard_fork_initiation_action = 2; // Initiate a Hard Fork
    TreasuryWithdrawalsAction treasury_withdrawals_action = 3; // Withdraw from the Treasury
    NoConfidenceAction no_confidence_action = 4; //
    UpdateCommitteeAction update_committee_action = 5; // Update the Constitution Committee
    NewConstitutionAction new_constitution_action = 6; // Replace the Constitution
    InfoAction info_action = 7; // Info action
  }
}

message GovernanceActionId {
  bytes transaction_id = 1;
  uint32 governance_action_index = 2;
}

message ParameterChangeAction {
  GovernanceActionId gov_action_id = 1;
  PParams protocol_param_update = 2; // The updates proposed
  bytes policy_hash = 3;
}

message HardForkInitiationAction {
  GovernanceActionId gov_action_id = 1;
  ProtocolVersion protocol_version = 2; // The protocol version to fork to
}

message TreasuryWithdrawalsAction {
  repeated WithdrawalAmount withdrawals = 1; // A list of the withdrawals to make
  bytes policy_hash = 2;
}

message WithdrawalAmount {
  bytes reward_account = 1;
  BigInt coin = 2;
}

message NoConfidenceAction {
  GovernanceActionId gov_action_id = 1;
}

message UpdateCommitteeAction {
  GovernanceActionId gov_action_id = 1;
  repeated StakeCredential remove_committee_credentials = 2; // Committee members to remove (if any)
  repeated NewCommitteeCredentials new_committee_credentials = 3; // The new committee members
  RationalNumber new_committee_threshold = 4; // The required threshold for the committee
}

message NewConstitutionAction {
  GovernanceActionId gov_action_id = 1;
  Constitution constitution = 2; // The Constitution proposed
}

message InfoAction {}

message Constitution {
  Anchor anchor = 1; // Anchor to the new document
  bytes hash = 2; // Hash of the document
}

// The new committee credential are passed as a map where the key is the committee cold credential hash
// and the value is the expiration epoch for that credential
message NewCommitteeCredentials {
  StakeCredential committee_cold_credential = 1;
  uint32 expires_epoch = 2;
}

// Contains the header information for a block.
message BlockHeader {
  uint64 slot = 1; // Slot number.
  bytes hash = 2; // Block hash.
  uint64 height = 3; // Block height.
}

// Contains the transaction data for a block.
message BlockBody {
  repeated Tx tx = 1; // List of transactions.
}

// Represents a complete block, including header and body.
message Block {
  BlockHeader header = 1; // Block header.
  BlockBody body = 2; // Block body.
  uint64 timestamp = 3; // Block ms timestamp
}

// Represents bootstrap keys from Byron era
message BootstrapWitness {
  bytes vkey = 1; // Verification key.
  bytes signature = 2; // Signature generated using the associated private key.
  bytes chain_code = 3; // 32 bytes of chain code
  bytes attributes = 4; // key attributes
}

// Represents a VKey witness used to sign a transaction.
message VKeyWitness {
  bytes vkey = 1; // Verification key.
  bytes signature = 2; // Signature generated using the associated private key.
}

// Represents a native script in Cardano.
message NativeScript {
  oneof native_script {
    bytes script_pubkey_hash = 1; // Script based on an address key hash.
    NativeScriptList script_all = 2; // Script that requires all nested scripts to be satisfied.
    NativeScriptList script_any = 3; // Script that requires any of the nested scripts to be satisfied.
    ScriptNOfK script_n_of_k = 4; // Script that requires k out of n nested scripts to be satisfied.
    uint64 invalid_before = 5; // Slot number before which the script is invalid.
    uint64 invalid_hereafter = 6; // Slot number after which the script is invalid.
  }
}

// Represents a list of native scripts.
message NativeScriptList {
  repeated NativeScript items = 1; // List of native scripts.
}

// Represents a "k out of n" native script.
message ScriptNOfK {
  uint32 k = 1; // The number of required satisfied scripts.
  repeated NativeScript scripts = 2; // List of native scripts.
}

// Represents a constructor for Plutus data in Cardano.
message Constr {
  uint32 tag = 1;
  uint64 any_constructor = 2;
  repeated PlutusData fields = 3;
}

// Represents a big integer for Plutus data in Cardano.
// The representation here follows CBOR specification for bignums:
// https://www.rfc-editor.org/rfc/rfc8949.html#name-bignums section 3.4.3.
message BigInt {
  oneof big_int {
    int64 int = 1; // Stores value fitting within int64 range
    bytes big_u_int = 2; // Stores unsigned value exceeding int64 range
    bytes big_n_int = 3; // Stores negative value `n` exceeding int64 range as `-1 - n`
  }
}

// Represents a key-value pair for Plutus data in Cardano.
message PlutusDataPair {
  PlutusData key = 1; // Key of the pair.
  PlutusData value = 2; // Value of the pair.
}

// Represents a Plutus data item in Cardano.
message PlutusData {
  oneof plutus_data {
    Constr constr = 2; // Constructor.
    PlutusDataMap map = 3; // Map of Plutus data.
    BigInt big_int = 4; // Big integer.
    bytes bounded_bytes = 5; // Bounded bytes.
    PlutusDataArray array = 6; // Array of Plutus data.
  }
}

// Represents a map of Plutus data in Cardano.
message PlutusDataMap {
  repeated PlutusDataPair pairs = 1; // List of key-value pairs.
}

// Represents an array of Plutus data in Cardano.
message PlutusDataArray {
  repeated PlutusData items = 1; // List of Plutus data items.
}

// Represents a script in Cardano.
message Script {
  oneof script {
    NativeScript native = 1; // Native script.
    bytes plutus_v1 = 2; // Plutus V1 script.
    bytes plutus_v2 = 3; // Plutus V2 script.
    bytes plutus_v3 = 4; // Plutus V3 script.
    bytes plutus_v4 = 5; // Plutus V4 script.
  }
}

message Metadatum {
  oneof metadatum {
    int64 int = 1;
    bytes bytes = 2;
    string text = 3;
    MetadatumArray array = 4;
    MetadatumMap map = 5;
  }
}

message MetadatumArray {
  repeated Metadatum items = 1;
}

message MetadatumMap {
  repeated MetadatumPair pairs = 1;
}

message MetadatumPair {
  Metadatum key = 1;
  Metadatum value = 2;
}

message Metadata {
  uint64 label = 1;
  Metadatum value = 2;
}

// Represents a stake credential in Cardano.
message StakeCredential {
  oneof stake_credential {
    bytes addr_key_hash = 1; // Address key hash.
    bytes script_hash = 2; // Script hash.
  }
}

// Represents a rational number as a fraction.
message RationalNumber {
  int32 numerator = 1;
  uint32 denominator = 2;
}

// Represents a relay in Cardano.
message Relay {
  bytes ip_v4 = 1;
  bytes ip_v6 = 2;
  string dns_name = 3;
  uint32 port = 4;
}

// Represents pool metadata in Cardano.
message PoolMetadata {
  string url = 1;
  bytes hash = 2;
}

// Represents a certificate in Cardano.
message Certificate {
  oneof certificate {
    StakeCredential stake_registration = 1; // Stake registration certificate.
    StakeCredential stake_deregistration = 2; // Stake deregistration certificate.
    StakeDelegationCert stake_delegation = 3; // Stake delegation certificate.
    PoolRegistrationCert pool_registration = 4; // Pool registration certificate.
    PoolRetirementCert pool_retirement = 5; // Pool retirement certificate.
    GenesisKeyDelegationCert genesis_key_delegation = 6; // Genesis key delegation certificate.
    MirCert mir_cert = 7; // Move instantaneous rewards certificate.
    RegCert reg_cert = 8; // Registration certificate.
    UnRegCert unreg_cert = 9; // Unregistration certificate.
    VoteDelegCert vote_deleg_cert = 10; // Vote delegation certificate.
    StakeVoteDelegCert stake_vote_deleg_cert = 11; // Stake and vote delegation certificate.
    StakeRegDelegCert stake_reg_deleg_cert = 12; // Stake registration and delegation certificate.
    VoteRegDelegCert vote_reg_deleg_cert = 13; // Vote registration and delegation certificate.
    StakeVoteRegDelegCert stake_vote_reg_deleg_cert = 14; // Stake and vote registration and delegation certificate.
    AuthCommitteeHotCert auth_committee_hot_cert = 15; // Authorize committee hot key certificate.
    ResignCommitteeColdCert resign_committee_cold_cert = 16; // Resign committee cold key certificate.
    RegDRepCert reg_drep_cert = 17; // Register DRep certificate.
    UnRegDRepCert unreg_drep_cert = 18; // Unregister DRep certificate.
    UpdateDRepCert update_drep_cert = 19; // Update DRep certificate.
  }
  Redeemer redeemer = 100; // Redeemer for the Plutus script.
}

// Represents a stake delegation certificate in Cardano.
message StakeDelegationCert {
  StakeCredential stake_credential = 1; // Stake credential.
  bytes pool_keyhash = 2; // Pool key hash.
}

// Represents a pool registration certificate in Cardano.
message PoolRegistrationCert {
  bytes operator = 1; // Operator key hash.
  bytes vrf_keyhash = 2; // VRF key hash.
  BigInt pledge = 3; // Pledge amount.
  BigInt cost = 4; // Pool cost.
  RationalNumber margin = 5; // Pool margin.
  bytes reward_account = 6; // Reward account.
  repeated bytes pool_owners = 7; // List of pool owner key hashes.
  repeated Relay relays = 8; // List of relays.
  PoolMetadata pool_metadata = 9; // Pool metadata.
}

// Represents a pool retirement certificate in Cardano.
message PoolRetirementCert {
  bytes pool_keyhash = 1; // Pool key hash.
  uint64 epoch = 2; // Retirement epoch.
}

// Represents a genesis key delegation certificate in Cardano.
message GenesisKeyDelegationCert {
  bytes genesis_hash = 1; // Genesis hash.
  bytes genesis_delegate_hash = 2; // Genesis delegate hash.
  bytes vrf_keyhash = 3; // VRF key hash.
}

enum MirSource {
  MIR_SOURCE_UNSPECIFIED = 0;
  MIR_SOURCE_RESERVES = 1;
  MIR_SOURCE_TREASURY = 2;
}

message MirTarget {
  StakeCredential stake_credential = 1;
  BigInt delta_coin = 2;
}

// Represents a move instantaneous reward certificate in Cardano.
message MirCert {
  MirSource from = 1;
  repeated MirTarget to = 2;
  uint64 other_pot = 3;
}

message RegCert {
  StakeCredential stake_credential = 1;
  BigInt coin = 2;
}

message UnRegCert {
  StakeCredential stake_credential = 1;
  BigInt coin = 2;
}

message DRep {
  oneof drep {
    bytes addr_key_hash = 1; // Address key hash
    bytes script_hash = 2; // Script hash
    bool abstain = 3; // Abstain
    bool no_confidence = 4; // No confidence
  }
}

message VoteDelegCert {
  StakeCredential stake_credential = 1;
  DRep drep = 2;
}

message StakeVoteDelegCert {
  StakeCredential stake_credential = 1;
  bytes pool_keyhash = 2;
  DRep drep = 3;
}

message StakeRegDelegCert {
  StakeCredential stake_credential = 1;
  bytes pool_keyhash = 2;
  BigInt coin = 3;
}

message VoteRegDelegCert {
  StakeCredential stake_credential = 1;
  DRep drep = 2;
  BigInt coin = 3;
}

message StakeVoteRegDelegCert {
  StakeCredential stake_credential = 1;
  bytes pool_keyhash = 2;
  DRep drep = 3;
  BigInt coin = 4;
}

message AuthCommitteeHotCert {
  StakeCredential committee_cold_credential = 1;
  StakeCredential committee_hot_credential = 2;
}

message Anchor {
  string url = 1;
  bytes content_hash = 2;
}

message ResignCommitteeColdCert {
  StakeCredential committee_cold_credential = 1;
  Anchor anchor = 2;
}

message RegDRepCert {
  StakeCredential drep_credential = 1;
  BigInt coin = 2;
  Anchor anchor = 3;
}

message UnRegDRepCert {
  StakeCredential drep_credential = 1;
  BigInt coin = 2;
}

message UpdateDRepCert {
  StakeCredential drep_credential = 1;
  Anchor anchor = 2;
}

// PATTERN MATCHING
// ================

// Pattern of an address that can be used to evaluate matching predicates.
message AddressPattern {
  optional bytes exact_address = 1; // The address should match this exact address value.
  optional bytes payment_part = 2; // The payment part of the address should match this value.
  optional bytes delegation_part = 3; // The delegation part of the address should match this value.
}

// Pattern of a native asset that can be used to evaluate matching predicates.
message AssetPattern {
  optional bytes policy_id = 1; // The asset should belong to this policy id
  optional bytes asset_name = 2; // The asset should present this name
}

// Pattern of a certificate that can be used to evaluate matching predicates.
message CertificatePattern {
  oneof certificate_type {
    StakeCredential stake_registration = 1; // Match stake registration for this credential
    StakeCredential stake_deregistration = 2; // Match stake deregistration for this credential
    StakeDelegationPattern stake_delegation = 3; // Match stake delegation pattern
    PoolRegistrationPattern pool_registration = 4; // Match pool registration pattern
    PoolRetirementPattern pool_retirement = 5; // Match pool retirement pattern
    bytes any_stake_credential = 6; // Match any certificate involving this stake credential
    bytes any_pool_keyhash = 7; // Match any certificate involving this pool
    bytes any_drep = 8; // Match any certificate involving this DRep
  }
}

// Pattern for stake delegation certificates
message StakeDelegationPattern {
  StakeCredential stake_credential = 1; // Match delegations from this credential
  bytes pool_keyhash = 2; // Match delegations to this pool
}

// Pattern for pool registration certificates
message PoolRegistrationPattern {
  bytes operator = 1; // Match registrations by this operator
  bytes pool_keyhash = 2; // Match registrations for this pool (derived from operator)
}

// Pattern for pool retirement certificates
message PoolRetirementPattern {
  bytes pool_keyhash = 1; // Match retirements of this pool
  uint64 epoch = 2; // Match retirements in this epoch
}

// Pattern of a tx output that can be used to evaluate matching predicates.
message TxOutputPattern {
  optional AddressPattern address = 1; // Match any address in the output that exhibits this pattern.
  optional AssetPattern asset = 2; // Match any asset in the output that exhibits this pattern.
}

// Pattern of a Tx that can be used to evaluate matching predicates.
message TxPattern {
  TxOutputPattern consumes = 1; // Match any input that exhibits this pattern.
  TxOutputPattern produces = 2; // Match any output that exhibits this pattern.
  AddressPattern has_address = 3; // Match any address (inputs, outputs, collateral, etc) that exhibits this pattern.
  AssetPattern moves_asset = 4; // Match any asset that exhibits this pattern.
  AssetPattern mints_asset = 5; // Match any tx that either mint or burn the the asset pattern.
  CertificatePattern has_certificate = 6; // Match any transaction that includes this certificate pattern.
}

// PARAMS
// ======

message ExUnits {
  uint64 steps = 1;
  uint64 memory = 2;
}

message ExPrices {
  RationalNumber steps = 1;
  RationalNumber memory = 2;
}

message ProtocolVersion {
  uint32 major = 1;
  uint32 minor = 2;
}

message CostModel {
  repeated int64 values = 1;
}

message CostModels {
  CostModel plutus_v1 = 1;
  CostModel plutus_v2 = 2;
  CostModel plutus_v3 = 3;
  CostModel plutus_v4 = 4;
}

message VotingThresholds {
  repeated RationalNumber thresholds = 1;
}

message PParams {
  BigInt coins_per_utxo_byte = 1; // The number of coins per UTXO byte.
  uint64 max_tx_size = 2; // The maximum transaction size.
  BigInt min_fee_coefficient = 3; // The minimum fee coefficient.
  BigInt min_fee_constant = 4; // The minimum fee constant.
  uint64 max_block_body_size = 5; // The maximum block body size.
  uint64 max_block_header_size = 6; // The maximum block header size.
  BigInt stake_key_deposit = 7; // The stake key deposit.
  BigInt pool_deposit = 8; // The pool deposit.
  uint64 pool_retirement_epoch_bound = 9; // The pool retirement epoch bound.
  uint64 desired_number_of_pools = 10; // The desired number of pools.
  RationalNumber pool_influence = 11; // The pool influence.
  RationalNumber monetary_expansion = 12; // The monetary expansion.
  RationalNumber treasury_expansion = 13; // The treasury expansion.
  BigInt min_pool_cost = 14; // The minimum pool cost.
  ProtocolVersion protocol_version = 15; // The protocol version.
  uint64 max_value_size = 16; // The maximum value size.
  uint64 collateral_percentage = 17; // The collateral percentage.
  uint64 max_collateral_inputs = 18; // The maximum collateral inputs.
  CostModels cost_models = 19; // The cost models.
  ExPrices prices = 20; // The prices.
  ExUnits max_execution_units_per_transaction = 21; // The maximum execution units per transaction.
  ExUnits max_execution_units_per_block = 22; // The maximum execution units per block.
  RationalNumber min_fee_script_ref_cost_per_byte = 23; // The minimum fee per script reference byte.
  VotingThresholds pool_voting_thresholds = 24; // The pool voting thresholds.
  VotingThresholds drep_voting_thresholds = 25; // The drep voting thresholds.
  uint32 min_committee_size = 26; // The minimum committee size.
  uint64 committee_term_limit = 27; // The committee term limit.
  uint64 governance_action_validity_period = 28; // The governance action validity period.
  BigInt governance_action_deposit = 29; // The governance action deposit.
  BigInt drep_deposit = 30; // The drep deposit.
  uint64 drep_inactivity_period = 31; // The drep inactivity period.
}

message EraBoundary {
  uint64 time = 1; // ms timestamp
  uint64 slot = 2; // absolute slot number of the first block of this era
  uint64 epoch = 3; // first epoch for this era
}

message EraSummary {
  string name = 1; // name of the era (ex: "shelley")
  EraBoundary start = 2; // start of this era
  EraBoundary end = 3; // end of this era (if the era has a well-defined ending)
  PParams protocol_params = 4; // protocol parameters for this era
}

message EraSummaries {
  repeated EraSummary summaries = 1;
}

// EVALUATION
// ==========

// A single evaluation report entry, used for script errors, execution traces,
// and transaction-level evaluation errors (e.g. balance mismatches). When the
// entry relates to a specific redeemer, purpose and index identify which one;
// for transaction-level errors these fields are absent.
message EvalReport {
  string msg = 1; // Human-readable message.
  optional RedeemerPurpose purpose = 2; // Purpose of the redeemer that produced this entry.
  optional uint32 index = 3; // Index of the redeemer within its purpose.
}

// Result of evaluating a transaction against the current ledger state.
message TxEval {
  BigInt fee = 1; // Computed minimum fee for the transaction.
  ExUnits ex_units = 2; // Total execution units consumed across all redeemers.
  repeated EvalReport errors = 3; // Script execution and transaction-level evaluation errors.
  repeated EvalReport traces = 4; // Per-redeemer script execution traces.
  repeated Redeemer redeemers = 5; // Redeemers with evaluated execution units.
}

// GENESIS CONFIGS
// ===============

message ExtraEntropy {
  string tag = 1;
}

message BlockVersionData {
  uint32 script_version = 1;
  string slot_duration = 2;
  string max_block_size = 3;
  string max_header_size = 4;
  string max_tx_size = 5;
  string max_proposal_size = 6;
  string mpc_thd = 7;
  string heavy_del_thd = 8;
  string update_vote_thd = 9;
  string update_proposal_thd = 10;
  string update_implicit = 11;
  SoftforkRule softfork_rule = 12;
  TxFeePolicy tx_fee_policy = 13;
  string unlock_stake_epoch = 14;
}

message SoftforkRule {
  string init_thd = 1;
  string min_thd = 2;
  string thd_decrement = 3;
}

message TxFeePolicy {
  string multiplier = 1;
  string summand = 2;
}

message ProtocolConsts {
  uint32 k = 1;
  uint32 protocol_magic = 2;
  uint32 vss_max_ttl = 3;
  uint32 vss_min_ttl = 4;
}

message HeavyDelegation {
  string cert = 1;
  string delegate_pk = 2;
  string issuer_pk = 3;
  uint32 omega = 4;
}

message VssCert {
  uint32 expiry_epoch = 1;
  string signature = 2;
  string signing_key = 3;
  string vss_key = 4;
}

message GenDelegs {
  string delegate = 1;
  string vrf = 2;
}

message PoolVotingThresholds {
  RationalNumber motion_no_confidence = 1;
  RationalNumber committee_normal = 2;
  RationalNumber committee_no_confidence = 3;
  RationalNumber hard_fork_initiation = 4;
  RationalNumber pp_security_group = 5;
}

message DRepVotingThresholds {
  RationalNumber motion_no_confidence = 1;
  RationalNumber committee_normal = 2;
  RationalNumber committee_no_confidence = 3;
  RationalNumber update_to_constitution = 4;
  RationalNumber hard_fork_initiation = 5;
  RationalNumber pp_network_group = 6;
  RationalNumber pp_economic_group = 7;
  RationalNumber pp_technical_group = 8;
  RationalNumber pp_gov_group = 9;
  RationalNumber treasury_withdrawal = 10;
}

message Committee {
  map<string, uint64> members = 1;
  RationalNumber threshold = 2;
}

message CostModelMap {
  CostModel plutus_v1 = 1;
  CostModel plutus_v2 = 2;
  CostModel plutus_v3 = 3;
  CostModel plutus_v4 = 4;
}

// Unified Genesis configuration containing all parameters from all eras
message Genesis {
  // ============ Byron Era Fields ============
  map<string, string> avvm_distr = 1;
  BlockVersionData block_version_data = 2;
  string fts_seed = 3;
  ProtocolConsts protocol_consts = 4;
  uint64 start_time = 5;
  map<string, uint64> boot_stakeholders = 6;
  map<string, HeavyDelegation> heavy_delegation = 7;
  map<string, string> non_avvm_balances = 8;
  map<string, VssCert> vss_certs = 9;

  // ============ Shelley Era Fields ============
  RationalNumber active_slots_coeff = 10;
  uint32 epoch_length = 11;
  map<string, GenDelegs> gen_delegs = 12;
  map<string, BigInt> initial_funds = 13;
  uint32 max_kes_evolutions = 14;
  BigInt max_lovelace_supply = 15;
  string network_id = 16;
  uint32 network_magic = 17;
  PParams protocol_params = 18; // Using PParams as it's a superset of all protocol parameters
  uint32 security_param = 19;
  uint32 slot_length = 20;
  uint32 slots_per_kes_period = 21;
  string system_start = 22;
  uint32 update_quorum = 23;

  // ============ Alonzo Era Fields ============
  BigInt lovelace_per_utxo_word = 24;
  ExPrices execution_prices = 25;
  ExUnits max_tx_ex_units = 26;
  ExUnits max_block_ex_units = 27;
  uint32 max_value_size = 28;
  uint32 collateral_percentage = 29;
  uint32 max_collateral_inputs = 30;
  CostModelMap cost_models = 31;

  // ============ Conway Era Fields ============
  Committee committee = 32;
  Constitution constitution = 33;
  uint64 committee_min_size = 34;
  uint64 committee_max_term_length = 35;
  uint64 gov_action_lifetime = 36;
  BigInt gov_action_deposit = 37;
  BigInt drep_deposit = 38;
  uint64 drep_activity = 39;
  RationalNumber min_fee_ref_script_cost_per_byte = 40;
  DRepVotingThresholds drep_voting_thresholds = 41;
  PoolVotingThresholds pool_voting_thresholds = 42;
}
