from .canister import Canister

governance_did = """type AccountIdentifier = record {
  hash : blob;
};

type Action = variant {
  RegisterKnownNeuron : KnownNeuron;
  DeregisterKnownNeuron : DeregisterKnownNeuron;
  ManageNeuron : ManageNeuronProposal;
  UpdateCanisterSettings : UpdateCanisterSettings;
  InstallCode : InstallCode;
  StopOrStartCanister : StopOrStartCanister;
  CreateServiceNervousSystem : CreateServiceNervousSystem;
  ExecuteNnsFunction : ExecuteNnsFunction;
  RewardNodeProvider : RewardNodeProvider;
  OpenSnsTokenSwap : OpenSnsTokenSwap;
  SetSnsTokenSwapOpenTimeWindow : SetSnsTokenSwapOpenTimeWindow;
  SetDefaultFollowees : SetDefaultFollowees;
  RewardNodeProviders : RewardNodeProviders;
  ManageNetworkEconomics : NetworkEconomics;
  ApproveGenesisKyc : Principals;
  AddOrRemoveNodeProvider : AddOrRemoveNodeProvider;
  Motion : Motion;
  FulfillSubnetRentalRequest : FulfillSubnetRentalRequest;
};

type AddHotKey = record {
  new_hot_key : opt principal;
};

type AddOrRemoveNodeProvider = record {
  change : opt Change;
};

type Amount = record {
  e8s : nat64;
};

type ApproveGenesisKyc = record {
  principals : vec principal;
};

type Ballot = record {
  vote : int32;
  voting_power : nat64;
};

type BallotInfo = record {
  vote : int32;
  proposal_id : opt ProposalId;
};

type By = variant {
  NeuronIdOrSubaccount : record {};
  MemoAndController : ClaimOrRefreshNeuronFromAccount;
  Memo : nat64;
};

type Canister = record {
  id : opt principal;
};

type CanisterSettings = record {
  freezing_threshold : opt nat64;
  controllers : opt Controllers;
  log_visibility : opt int32;
  wasm_memory_limit : opt nat64;
  memory_allocation : opt nat64;
  compute_allocation : opt nat64;
  wasm_memory_threshold : opt nat64;
};

type CanisterStatusResultV2 = record {
  status : opt int32;
  freezing_threshold : opt nat64;
  controllers : vec principal;
  memory_size : opt nat64;
  cycles : opt nat64;
  idle_cycles_burned_per_day : opt nat64;
  module_hash : blob;
};

type CanisterSummary = record {
  status : opt CanisterStatusResultV2;
  canister_id : opt principal;
};

type Change = variant {
  ToRemove : NodeProvider;
  ToAdd : NodeProvider;
};

type ChangeAutoStakeMaturity = record {
  requested_setting_for_auto_stake_maturity : bool;
};

type ClaimOrRefresh = record {
  by : opt By;
};

type ClaimOrRefreshNeuronFromAccount = record {
  controller : opt principal;
  memo : nat64;
};

type ClaimOrRefreshNeuronFromAccountResponse = record {
  result : opt Result_1;
};

type ClaimOrRefreshResponse = record {
  refreshed_neuron_id : opt NeuronId;
};

// This is one way for a neuron to make sure that its deciding_voting_power is
// not less than its potential_voting_power. See the description of those fields
// in Neuron.
type RefreshVotingPower = record {
  // Intentionally left blank.
};

type RefreshVotingPowerResponse = record {
  // Intentionally left blank.
  //
  // We could add information such as the value in the neuron's
  // voting_power_refreshed_timestamp_second's field, but let's keep things
  // minimal until we discover there is a "real need". YAGNI.
};

type DisburseMaturity = record {
  percentage_to_disburse : nat32;
  to_account : opt Account;
  to_account_identifier: opt AccountIdentifier;
};

type Account = record {
  owner: opt principal;
  subaccount: opt blob;
};

type DisburseMaturityResponse = record {
  amount_disbursed_e8s : opt nat64;
};

type SetFollowing = record {
  topic_following : opt vec FolloweesForTopic;
};

type FolloweesForTopic = record {
  followees : opt vec NeuronId;
  topic : opt int32;
};

type SetFollowingResponse = record {
};

// KEEP THIS IN SYNC WITH ManageNeuronCommandRequest!
type ManageNeuronProposalCommand = variant {
  Spawn : Spawn;
  Split : Split;
  Follow : Follow;
  ClaimOrRefresh : ClaimOrRefresh;
  Configure : Configure;
  RegisterVote : RegisterVote;
  Merge : Merge;
  DisburseToNeuron : DisburseToNeuron;
  MakeProposal : Proposal;
  StakeMaturity : StakeMaturity;
  MergeMaturity : MergeMaturity;
  Disburse : Disburse;
  RefreshVotingPower : RefreshVotingPower;
  DisburseMaturity : DisburseMaturity;
  SetFollowing : SetFollowing;

  // KEEP THIS IN SYNC WITH ManageNeuronCommandRequest!
};

type Command_1 = variant {
  Error : GovernanceError;
  Spawn : SpawnResponse;
  Split : SpawnResponse;
  Follow : record {};
  ClaimOrRefresh : ClaimOrRefreshResponse;
  Configure : record {};
  RegisterVote : record {};
  Merge : MergeResponse;
  DisburseToNeuron : SpawnResponse;
  MakeProposal : MakeProposalResponse;
  StakeMaturity : StakeMaturityResponse;
  MergeMaturity : MergeMaturityResponse;
  Disburse : DisburseResponse;
  RefreshVotingPower : RefreshVotingPowerResponse;
  DisburseMaturity : DisburseMaturityResponse;
  SetFollowing : SetFollowingResponse;
};

type Command_2 = variant {
  Spawn : NeuronId;
  Split : Split;
  Configure : Configure;
  Merge : Merge;
  DisburseToNeuron : DisburseToNeuron;
  SyncCommand : record {};
  ClaimOrRefreshNeuron : ClaimOrRefresh;
  MergeMaturity : MergeMaturity;
  Disburse : Disburse;
};

type Committed = record {
  total_direct_contribution_icp_e8s : opt nat64;
  total_neurons_fund_contribution_icp_e8s : opt nat64;
  sns_governance_canister_id : opt principal;
};

type Committed_1 = record {
  total_direct_participation_icp_e8s : opt nat64;
  total_neurons_fund_participation_icp_e8s : opt nat64;
  sns_governance_canister_id : opt principal;
};

type Configure = record {
  operation : opt Operation;
};

type Controllers = record {
  controllers : vec principal;
};

type Countries = record {
  iso_codes : vec text;
};

type CreateServiceNervousSystem = record {
  url : opt text;
  governance_parameters : opt GovernanceParameters;
  fallback_controller_principal_ids : vec principal;
  logo : opt Image;
  name : opt text;
  ledger_parameters : opt LedgerParameters;
  description : opt text;
  dapp_canisters : vec Canister;
  swap_parameters : opt SwapParameters;
  initial_token_distribution : opt InitialTokenDistribution;
};

type DateRangeFilter = record {
  start_timestamp_seconds : opt nat64;
  end_timestamp_seconds : opt nat64;
};

type Decimal = record {
  human_readable : opt text;
};

type DerivedProposalInformation = record {
  swap_background_information : opt SwapBackgroundInformation;
};

type DeveloperDistribution = record {
  developer_neurons : vec NeuronDistribution;
};

type Disburse = record {
  to_account : opt AccountIdentifier;
  amount : opt Amount;
};

type DisburseResponse = record {
  transfer_block_height : nat64;
};

type DisburseToNeuron = record {
  dissolve_delay_seconds : nat64;
  kyc_verified : bool;
  amount_e8s : nat64;
  new_controller : opt principal;
  nonce : nat64;
};

type DissolveState = variant {
  DissolveDelaySeconds : nat64;
  WhenDissolvedTimestampSeconds : nat64;
};

type Duration = record {
  seconds : opt nat64;
};

type ExecuteNnsFunction = record {
  nns_function : int32;
  payload : blob;
};

type Follow = record {
  topic : int32;
  followees : vec NeuronId;
};

type Followees = record {
  followees : vec NeuronId;
};

type GetNeuronsFundAuditInfoRequest = record {
  nns_proposal_id : opt ProposalId;
};

type GetNeuronsFundAuditInfoResponse = record {
  result : opt Result_6;
};

type GlobalTimeOfDay = record {
  seconds_after_utc_midnight : opt nat64;
};

type Governance = record {
  default_followees : vec record { int32; Followees };
  most_recent_monthly_node_provider_rewards : opt MonthlyNodeProviderRewards;
  maturity_modulation_last_updated_at_timestamp_seconds : opt nat64;
  wait_for_quiet_threshold_seconds : nat64;
  metrics : opt GovernanceCachedMetrics;
  neuron_management_voting_period_seconds : opt nat64;
  node_providers : vec NodeProvider;
  cached_daily_maturity_modulation_basis_points : opt int32;
  economics : opt NetworkEconomics;
  restore_aging_summary : opt RestoreAgingSummary;
  spawning_neurons : opt bool;
  latest_reward_event : opt RewardEvent;
  to_claim_transfers : vec NeuronStakeTransfer;
  short_voting_period_seconds : nat64;
  proposals : vec record { nat64; ProposalData };
  xdr_conversion_rate : opt XdrConversionRate;
  in_flight_commands : vec record { nat64; NeuronInFlightCommand };
  neurons : vec record { nat64; Neuron };
  genesis_timestamp_seconds : nat64;
};

type GovernanceCachedMetrics = record {
  total_maturity_e8s_equivalent : nat64;
  not_dissolving_neurons_e8s_buckets : vec record { nat64; float64 };
  dissolving_neurons_staked_maturity_e8s_equivalent_sum : nat64;
  garbage_collectable_neurons_count : nat64;
  dissolving_neurons_staked_maturity_e8s_equivalent_buckets : vec record {
    nat64;
    float64;
  };
  neurons_with_invalid_stake_count : nat64;
  not_dissolving_neurons_count_buckets : vec record { nat64; nat64 };
  ect_neuron_count : nat64;
  total_supply_icp : nat64;
  neurons_with_less_than_6_months_dissolve_delay_count : nat64;
  dissolved_neurons_count : nat64;
  community_fund_total_maturity_e8s_equivalent : nat64;
  total_staked_e8s_seed : nat64;
  total_staked_maturity_e8s_equivalent_ect : nat64;
  total_staked_e8s : nat64;
  not_dissolving_neurons_count : nat64;
  total_locked_e8s : nat64;
  neurons_fund_total_active_neurons : nat64;
  total_voting_power_non_self_authenticating_controller : opt nat64;
  total_staked_maturity_e8s_equivalent : nat64;
  not_dissolving_neurons_e8s_buckets_ect : vec record { nat64; float64 };
  total_staked_e8s_ect : nat64;
  not_dissolving_neurons_staked_maturity_e8s_equivalent_sum : nat64;
  dissolved_neurons_e8s : nat64;
  total_staked_e8s_non_self_authenticating_controller : opt nat64;
  dissolving_neurons_e8s_buckets_seed : vec record { nat64; float64 };
  neurons_with_less_than_6_months_dissolve_delay_e8s : nat64;
  not_dissolving_neurons_staked_maturity_e8s_equivalent_buckets : vec record {
    nat64;
    float64;
  };
  dissolving_neurons_count_buckets : vec record { nat64; nat64 };
  dissolving_neurons_e8s_buckets_ect : vec record { nat64; float64 };
  dissolving_neurons_count : nat64;
  dissolving_neurons_e8s_buckets : vec record { nat64; float64 };
  total_staked_maturity_e8s_equivalent_seed : nat64;
  community_fund_total_staked_e8s : nat64;
  not_dissolving_neurons_e8s_buckets_seed : vec record { nat64; float64 };
  timestamp_seconds : nat64;
  seed_neuron_count : nat64;
  spawning_neurons_count : nat64;

  non_self_authenticating_controller_neuron_subset_metrics : opt NeuronSubsetMetrics;
  public_neuron_subset_metrics : opt NeuronSubsetMetrics;
  declining_voting_power_neuron_subset_metrics : opt NeuronSubsetMetrics;
  fully_lost_voting_power_neuron_subset_metrics : opt NeuronSubsetMetrics;
};

type GovernanceError = record {
  error_message : text;
  error_type : int32;
};

type GovernanceParameters = record {
  neuron_maximum_dissolve_delay_bonus : opt Percentage;
  neuron_maximum_age_for_age_bonus : opt Duration;
  neuron_maximum_dissolve_delay : opt Duration;
  neuron_minimum_dissolve_delay_to_vote : opt Duration;
  neuron_maximum_age_bonus : opt Percentage;
  neuron_minimum_stake : opt Tokens;
  proposal_wait_for_quiet_deadline_increase : opt Duration;
  proposal_initial_voting_period : opt Duration;
  proposal_rejection_fee : opt Tokens;
  voting_reward_parameters : opt VotingRewardParameters;
};

type IdealMatchedParticipationFunction = record {
  serialized_representation : opt text;
};

type Image = record {
  base64_encoding : opt text;
};

type IncreaseDissolveDelay = record {
  additional_dissolve_delay_seconds : nat32;
};

type InitialTokenDistribution = record {
  treasury_distribution : opt SwapDistribution;
  developer_distribution : opt DeveloperDistribution;
  swap_distribution : opt SwapDistribution;
};

type InstallCode = record {
  skip_stopping_before_installing : opt bool;
  wasm_module_hash : opt blob;
  canister_id : opt principal;
  arg_hash : opt blob;
  install_mode : opt int32;
};

type InstallCodeRequest = record {
  arg : opt blob;
  wasm_module : opt blob;
  skip_stopping_before_installing : opt bool;
  canister_id : opt principal;
  install_mode : opt int32;
};

type KnownNeuron = record {
  id : opt NeuronId;
  known_neuron_data : opt KnownNeuronData;
};

type DeregisterKnownNeuron = record {
  id : opt NeuronId;
};

type KnownNeuronData = record {
  name : text;
  description : opt text;
  // Links related to the known neuron. Can be links to social URLs (OpenChat, X, etc.), or a homepage.
  links : opt vec text;
  // Topics that the known neuron is committed to always vote on.
  // Note regarding the type: the first `opt` makes it so that the field can be renamed/deprecated
  // in the future, and the second `opt` makes it so that an older client not recognizing a new
  // variant can still get the rest of the `vec`.
  committed_topics : opt vec opt TopicToFollow;
};

type LedgerParameters = record {
  transaction_fee : opt Tokens;
  token_symbol : opt text;
  token_logo : opt Image;
  token_name : opt text;
};

type ListKnownNeuronsResponse = record {
  known_neurons : vec KnownNeuron;
};

// Parameters of the list_neurons method.
type ListNeurons = record {
  // These fields select neurons to be in the result set.
  neuron_ids : vec nat64;
  include_neurons_readable_by_caller : bool;

  // Only has an effect when include_neurons_readable_by_caller.
  include_empty_neurons_readable_by_caller : opt bool;

  // When a public neuron is a member of the result set, include it in the
  // full_neurons field (of ListNeuronsResponse). This does not affect which
  // neurons are part of the result set.
  include_public_neurons_in_full_neurons : opt bool;

  page_number: opt nat64;
  page_size: opt nat64;
  neuron_subaccounts: opt vec NeuronSubaccount;
};

type NeuronSubaccount = record {
  subaccount : blob;
};

// Output of the list_neurons method.
type ListNeuronsResponse = record {
  // Per the NeuronInfo type, this is a redacted view of the neurons in the
  // result set consisting of information that require no special privileges to
  // view.
  neuron_infos : vec record { nat64; NeuronInfo };

  // If the caller has the necessary special privileges (or the neuron is
  // public, and the request sets include_public_neurons_in_full_neurons to
  // true), then all the information about the neurons in the result set is made
  // available here.
  full_neurons : vec Neuron;

  total_pages_available: opt nat64;
};

type ListNodeProviderRewardsRequest = record {
  date_filter : opt DateRangeFilter;
};

type ListNodeProviderRewardsResponse = record {
  rewards : vec MonthlyNodeProviderRewards;
};

type ListNodeProvidersResponse = record {
  node_providers : vec NodeProvider;
};

type ListProposalInfoRequest = record {
  include_reward_status : vec int32;
  omit_large_fields : opt bool;
  before_proposal : opt ProposalId;
  limit : nat32;
  exclude_topic : vec int32;
  include_all_manage_neuron_proposals : opt bool;
  include_status : vec int32;
  return_self_describing_action : opt bool;
};

type ListProposalInfoResponse = record {
  proposal_info : vec ProposalInfo;
};

type MakeProposalRequest = record {
  url : text;
  title : opt text;
  action : opt ProposalActionRequest;
  summary : text;
};

type MakeProposalResponse = record {
  message : opt text;
  proposal_id : opt ProposalId;
};

// Not to be confused with ManageNeuronRequest. This is only used to represent a manage neuron proposal. 
// (Yes, this is very structurally similar to that, but not actually exactly equivalent)
type ManageNeuronProposal = record {
  id : opt NeuronId;
  command : opt ManageNeuronProposalCommand;
  neuron_id_or_subaccount : opt NeuronIdOrSubaccount;
};

// KEEP THIS IN SYNC WITH COMMAND!
type ManageNeuronCommandRequest = variant {
  Spawn : Spawn;
  Split : Split;
  Follow : Follow;
  ClaimOrRefresh : ClaimOrRefresh;
  Configure : Configure;
  RegisterVote : RegisterVote;
  Merge : Merge;
  DisburseToNeuron : DisburseToNeuron;
  MakeProposal : MakeProposalRequest;
  StakeMaturity : StakeMaturity;
  MergeMaturity : MergeMaturity;
  Disburse : Disburse;
  RefreshVotingPower : RefreshVotingPower;
  DisburseMaturity : DisburseMaturity;
  SetFollowing : SetFollowing;

  // KEEP THIS IN SYNC WITH COMMAND!
};

// Parameters of the manage_neuron method.
type ManageNeuronRequest = record {
  // Which neuron to operate on.
  neuron_id_or_subaccount : opt NeuronIdOrSubaccount;

  // What operation to perform on the neuron.
  command : opt ManageNeuronCommandRequest;

  // Deprecated. Use neuron_id_or_subaccount instead.
  id : opt NeuronId;
};

// Output of the manage_neuron method.
type ManageNeuronResponse = record {
  // Corresponds to the command field in ManageNeuronRequest, which determines
  // what operation was performed.
  command : opt Command_1;
};

type Merge = record {
  source_neuron_id : opt NeuronId;
};

type MergeMaturity = record {
  percentage_to_merge : nat32;
};

type MergeMaturityResponse = record {
  merged_maturity_e8s : nat64;
  new_stake_e8s : nat64;
};

type MergeResponse = record {
  target_neuron : opt Neuron;
  source_neuron : opt Neuron;
  target_neuron_info : opt NeuronInfo;
  source_neuron_info : opt NeuronInfo;
};

type DateUtc = record {
  year : nat32;
  month : nat32;
  day : nat32;
};

type MonthlyNodeProviderRewards = record {
  minimum_xdr_permyriad_per_icp : opt nat64;
  registry_version : opt nat64;
  algorithm_version : opt nat32;
  node_providers : vec NodeProvider;
  timestamp : nat64;
  start_date : opt DateUtc;
  end_date : opt DateUtc;
  rewards : vec RewardNodeProvider;
  xdr_conversion_rate : opt XdrConversionRate;
  maximum_node_provider_rewards_e8s : opt nat64;
};

type Motion = record {
  motion_text : text;
};

type NetworkEconomics = record {
  neuron_minimum_stake_e8s : nat64;
  max_proposals_to_keep_per_topic : nat32;
  neuron_management_fee_per_proposal_e8s : nat64;
  reject_cost_e8s : nat64;
  transaction_fee_e8s : nat64;
  neuron_spawn_dissolve_delay_seconds : nat64;
  minimum_icp_xdr_rate : nat64;
  maximum_node_provider_rewards_e8s : nat64;
  neurons_fund_economics : opt NeuronsFundEconomics;

  // Parameters that affect the voting power of neurons.
  voting_power_economics : opt VotingPowerEconomics;
};

// Parameters that affect the voting power of neurons.
type VotingPowerEconomics = record {
  // If a neuron has not "refreshed" its voting power after this amount of time,
  // its deciding voting power starts decreasing linearly. See also
  // clear_following_after_seconds.
  //
  // For explanation of what "refresh" means in this context, see
  // https://dashboard.internetcomputer.org/proposal/132411
  //
  // Initially, set to 0.5 years. (The nominal length of a year is 365.25 days).
  start_reducing_voting_power_after_seconds : opt nat64;

  // After a neuron has experienced voting power reduction for this amount of
  // time, a couple of things happen:
  //
  //     1. Deciding voting power reaches 0.
  //
  //     2. Its following on topics other than NeuronManagement are cleared.
  //
  // Initially, set to 1/12 years.
  clear_following_after_seconds : opt nat64;

  // The minimum dissolve delay a neuron must have in order to be eligible to vote.
  //
  // Neurons with a dissolve delay lower than this threshold will not have 
  // voting power, even if they are otherwise active.
  //
  // This value is an essential part of the staking mechanism, promoting
  // long-term alignment with the network's governance.
  neuron_minimum_dissolve_delay_to_vote_seconds : opt nat64;
};

type Neuron = record {
  id : opt NeuronId;
  staked_maturity_e8s_equivalent : opt nat64;
  controller : opt principal;
  recent_ballots : vec BallotInfo;
  kyc_verified : bool;
  neuron_type : opt int32;
  not_for_profit : bool;
  maturity_e8s_equivalent : nat64;
  cached_neuron_stake_e8s : nat64;
  created_timestamp_seconds : nat64;
  auto_stake_maturity : opt bool;
  aging_since_timestamp_seconds : nat64;
  hot_keys : vec principal;
  account : blob;
  joined_community_fund_timestamp_seconds : opt nat64;
  dissolve_state : opt DissolveState;
  followees : vec record { int32; Followees };
  neuron_fees_e8s : nat64;
  visibility : opt int32;
  transfer : opt NeuronStakeTransfer;
  known_neuron_data : opt KnownNeuronData;
  spawn_at_timestamp_seconds : opt nat64;
  voting_power_refreshed_timestamp_seconds : opt nat64;

  // The amount of "sway" this neuron has when voting on proposals.
  //
  // When a proposal is created, each eligible neuron gets a "blank" ballot. The
  // amount of voting power in that ballot is set to the neuron's deciding
  // voting power at the time of proposal creation. There are two ways that a
  // proposal can become decided:
  //
  //   1. Early: Either more than half of the total voting power in the ballots
  //   votes in favor (then the proposal is approved), or at least half of the
  //   votal voting power in the ballots votes against (then, the proposal is
  //   rejected).
  //
  //   2. The proposal's voting deadline is reached. At that point, if there is
  //   more voting power in favor than against, and at least 3% of the total
  //   voting power voted in favor, then the proposal is approved. Otherwise, it
  //   is rejected.
  //
  // If a neuron regularly refreshes its voting power, this has the same value
  // as potential_voting_power. Actions that cause a refresh are as follows:
  //
  //     1. voting directly (not via following)
  //     2. set following
  //     3. refresh voting power
  //
  // (All of these actions are performed via the manage_neuron method.)
  //
  // However, if a neuron has not refreshed in a "long" time, this will be less
  // than potential voting power. See VotingPowerEconomics. As a further result
  // of less deciding voting power, not only does it have less influence on the
  // outcome of proposals, the neuron receives less voting rewards (when it
  // votes indirectly via following).
  //
  // For details, see https://dashboard.internetcomputer.org/proposal/132411.
  //
  // Per NNS policy, this is opt. Nevertheless, it will never be null.
  deciding_voting_power : opt nat64;

  // The amount of "sway" this neuron can have if it refreshes its voting power
  // frequently enough.
  //
  // Unlike deciding_voting_power, this does NOT take refreshing into account.
  // Rather, this only takes three factors into account:
  //
  //     1. (Net) staked amount - This is the "base" of a neuron's voting power.
  //        This primarily consists of the neuron's ICP balance.
  //
  //     2. Age - Neurons with more age have more voting power (all else being
  //        equal).
  //
  //     3. Dissolve delay - Neurons with longer dissolve delay have more voting
  //        power (all else being equal). Neurons with a dissolve delay of less
  //        than six months are not eligible to vote. Therefore, such neurons
  //        are considered to have 0 voting power.
  //
  // Per NNS policy, this is opt. Nevertheless, it will never be null.
  potential_voting_power : opt nat64;

  // The maturity disbursements in progress, i.e. the disbursements that are initiated but not
  // finalized. The finalization happens 7 days after the disbursement is initiated.
  maturity_disbursements_in_progress : opt vec MaturityDisbursement;
};

type NeuronBasketConstructionParameters = record {
  dissolve_delay_interval : opt Duration;
  count : opt nat64;
};

type NeuronBasketConstructionParameters_1 = record {
  dissolve_delay_interval_seconds : nat64;
  count : nat64;
};

type NeuronDistribution = record {
  controller : opt principal;
  dissolve_delay : opt Duration;
  memo : opt nat64;
  vesting_period : opt Duration;
  stake : opt Tokens;
};

type NeuronId = record {
  id : nat64;
};

type ProposalId = record {
  id : nat64;
};

type NeuronIdOrSubaccount = variant {
  Subaccount : blob;
  NeuronId : NeuronId;
};

type NeuronInFlightCommand = record {
  command : opt Command_2;
  timestamp : nat64;
};

type GetNeuronIndexRequest = record {
  exclusive_start_neuron_id: opt NeuronId;
  page_size: opt nat32;
};

type NeuronIndexData = record {
  neurons: vec NeuronInfo;
};

type GetNeuronIndexResult = variant {
  Ok : NeuronIndexData;
  Err : GovernanceError;
};

// A limit view of Neuron that allows some aspects of all neurons to be read by
// anyone (i.e. without having to be the neuron's controller nor one of its
// hotkeys).
//
// As such, the meaning of each field in this type is generally the same as the
// one of the same (or at least similar) name in Neuron.
type NeuronInfo = record {
  id: opt NeuronId;
  dissolve_delay_seconds : nat64;
  recent_ballots : vec BallotInfo;
  neuron_type : opt int32;
  created_timestamp_seconds : nat64;
  state : int32;

  // The amount of ICP (and staked maturity) locked in this neuron.
  //
  // This is the foundation of the neuron's voting power.
  //
  // cached_neuron_stake_e8s - neuron_fees_e8s + staked_maturity_e8s_equivalent
  stake_e8s : nat64;

  joined_community_fund_timestamp_seconds : opt nat64;
  retrieved_at_timestamp_seconds : nat64;
  visibility : opt int32;
  known_neuron_data : opt KnownNeuronData;
  age_seconds : nat64;

  // Deprecated. Use either deciding_voting_power or potential_voting_power
  // instead. Has the same value as deciding_voting_power.
  //
  // Previously, if a neuron had < 6 months dissolve delay (making it ineligible
  // to vote), this would not get set to 0 (zero). That was pretty confusing.
  // Now that this is set to deciding_voting_power, this actually does get
  // zeroed out.
  voting_power : nat64;

  voting_power_refreshed_timestamp_seconds : opt nat64;
  deciding_voting_power : opt nat64;
  potential_voting_power : opt nat64;
};

type NeuronStakeTransfer = record {
  to_subaccount : blob;
  neuron_stake_e8s : nat64;
  from : opt principal;
  memo : nat64;
  from_subaccount : blob;
  transfer_timestamp : nat64;
  block_height : nat64;
};

type NeuronSubsetMetrics = record {
  count : opt nat64;

  total_staked_e8s : opt nat64;
  total_maturity_e8s_equivalent : opt nat64;
  total_staked_maturity_e8s_equivalent : opt nat64;

  total_voting_power : opt nat64;
  total_deciding_voting_power : opt nat64;
  total_potential_voting_power : opt nat64;

  count_buckets : vec record { nat64; nat64 };

  staked_e8s_buckets : vec record { nat64; nat64 };
  maturity_e8s_equivalent_buckets : vec record { nat64; nat64 };
  staked_maturity_e8s_equivalent_buckets : vec record { nat64; nat64 };

  voting_power_buckets : vec record { nat64; nat64 };
  deciding_voting_power_buckets : vec record { nat64; nat64 };
  potential_voting_power_buckets : vec record { nat64; nat64 };
};

type NeuronsFundAuditInfo = record {
  final_neurons_fund_participation : opt NeuronsFundParticipation;
  initial_neurons_fund_participation : opt NeuronsFundParticipation;
  neurons_fund_refunds : opt NeuronsFundSnapshot;
};

type NeuronsFundData = record {
  final_neurons_fund_participation : opt NeuronsFundParticipation;
  initial_neurons_fund_participation : opt NeuronsFundParticipation;
  neurons_fund_refunds : opt NeuronsFundSnapshot;
};

type NeuronsFundEconomics = record {
  maximum_icp_xdr_rate : opt Percentage;
  neurons_fund_matched_funding_curve_coefficients : opt NeuronsFundMatchedFundingCurveCoefficients;
  max_theoretical_neurons_fund_participation_amount_xdr : opt Decimal;
  minimum_icp_xdr_rate : opt Percentage;
};

type NeuronsFundMatchedFundingCurveCoefficients = record {
  contribution_threshold_xdr : opt Decimal;
  one_third_participation_milestone_xdr : opt Decimal;
  full_participation_milestone_xdr : opt Decimal;
};

type NeuronsFundNeuron = record {
  controller : opt principal;
  hotkeys : opt Principals;
  is_capped : opt bool;
  nns_neuron_id : opt nat64;
  amount_icp_e8s : opt nat64;
};

type NeuronsFundNeuronPortion = record {
  controller : opt principal;
  hotkeys : vec principal;
  is_capped : opt bool;
  maturity_equivalent_icp_e8s : opt nat64;
  nns_neuron_id : opt NeuronId;
  amount_icp_e8s : opt nat64;
};

type NeuronsFundParticipation = record {
  total_maturity_equivalent_icp_e8s : opt nat64;
  intended_neurons_fund_participation_icp_e8s : opt nat64;
  direct_participation_icp_e8s : opt nat64;
  swap_participation_limits : opt SwapParticipationLimits;
  max_neurons_fund_swap_participation_icp_e8s : opt nat64;
  neurons_fund_reserves : opt NeuronsFundSnapshot;
  ideal_matched_participation_function : opt IdealMatchedParticipationFunction;
  allocated_neurons_fund_participation_icp_e8s : opt nat64;
};

type NeuronsFundSnapshot = record {
  neurons_fund_neuron_portions : vec NeuronsFundNeuronPortion;
};

type NodeProvider = record {
  id : opt principal;
  reward_account : opt AccountIdentifier;
};

type Ok = record {
  neurons_fund_audit_info : opt NeuronsFundAuditInfo;
};

type Ok_1 = record {
  neurons_fund_neuron_portions : vec NeuronsFundNeuron;
};

type OpenSnsTokenSwap = record {
  community_fund_investment_e8s : opt nat64;
  target_swap_canister_id : opt principal;
  params : opt Params;
};

type Operation = variant {
  RemoveHotKey : RemoveHotKey;
  AddHotKey : AddHotKey;
  ChangeAutoStakeMaturity : ChangeAutoStakeMaturity;
  StopDissolving : record {};
  StartDissolving : record {};
  IncreaseDissolveDelay : IncreaseDissolveDelay;
  SetVisibility : SetVisibility;
  JoinCommunityFund : record {};
  LeaveCommunityFund : record {};
  SetDissolveTimestamp : SetDissolveTimestamp;
};

type Params = record {
  min_participant_icp_e8s : nat64;
  neuron_basket_construction_parameters : opt NeuronBasketConstructionParameters_1;
  max_icp_e8s : nat64;
  swap_due_timestamp_seconds : nat64;
  min_participants : nat32;
  sns_token_e8s : nat64;
  sale_delay_seconds : opt nat64;
  max_participant_icp_e8s : nat64;
  min_direct_participation_icp_e8s : opt nat64;
  min_icp_e8s : nat64;
  max_direct_participation_icp_e8s : opt nat64;
};

type Percentage = record {
  basis_points : opt nat64;
};

type Principals = record {
  principals : vec principal;
};

type Proposal = record {
  url : text;
  title : opt text;
  action : opt Action;
  summary : text;
  self_describing_action : opt SelfDescribingProposalAction;
};

type ProposalActionRequest = variant {
  RegisterKnownNeuron : KnownNeuron;
  DeregisterKnownNeuron : DeregisterKnownNeuron;
  ManageNeuron : ManageNeuronRequest;
  UpdateCanisterSettings : UpdateCanisterSettings;
  InstallCode : InstallCodeRequest;
  StopOrStartCanister : StopOrStartCanister;
  CreateServiceNervousSystem : CreateServiceNervousSystem;
  ExecuteNnsFunction : ExecuteNnsFunction;
  RewardNodeProvider : RewardNodeProvider;
  RewardNodeProviders : RewardNodeProviders;
  ManageNetworkEconomics : NetworkEconomics;
  ApproveGenesisKyc : Principals;
  AddOrRemoveNodeProvider : AddOrRemoveNodeProvider;
  Motion : Motion;
  FulfillSubnetRentalRequest : FulfillSubnetRentalRequest;
};

// Creates a rented subnet from a rental request (in the Subnet Rental
// canister).
type FulfillSubnetRentalRequest = record {
  // Identifies which rental request to fulfill.
  //
  // (Identifying the rental request by user works, because a user can have at
  // most one rental request in the Subnet Rental canister).
  user : opt principal;

  // Which nodes will be members of the subnet.
  node_ids : opt vec principal;

  // What software the nodes will run.
  //
  // This must be approved by a prior proposal to bless an IC OS version.
  //
  // This is a FULL git commit ID in the ic repo. (Therefore, it must be a 40
  // character hexidecimal string, not an abbreviated git commit ID.)
  //
  // One way to find a suitable value is with the following command:
  //
  //     ic-admin \
  //         get-subnet 0 \
  //         --nns-urls https://nns.ic0.app \
  //     | grep replica_version_id
  //
  // Where to obtain a recent version of ic-admin:
  //
  //     https://github.com/dfinity/ic/releases/latest
  replica_version_id : opt text;
};

type ProposalData = record {
  id : opt ProposalId;
  failure_reason : opt GovernanceError;
  ballots : vec record { nat64; Ballot };
  proposal_timestamp_seconds : nat64;
  reward_event_round : nat64;
  failed_timestamp_seconds : nat64;
  neurons_fund_data : opt NeuronsFundData;
  reject_cost_e8s : nat64;
  derived_proposal_information : opt DerivedProposalInformation;
  latest_tally : opt Tally;
  sns_token_swap_lifecycle : opt int32;
  decided_timestamp_seconds : nat64;
  proposal : opt Proposal;
  proposer : opt NeuronId;
  wait_for_quiet_state : opt WaitForQuietState;
  executed_timestamp_seconds : nat64;
  original_total_community_fund_maturity_e8s_equivalent : opt nat64;
  total_potential_voting_power : opt nat64;
  topic: opt int32;
};

type ProposalInfo = record {
  id : opt ProposalId;
  status : int32;
  topic : int32;
  failure_reason : opt GovernanceError;
  ballots : vec record { nat64; Ballot };
  proposal_timestamp_seconds : nat64;
  reward_event_round : nat64;
  deadline_timestamp_seconds : opt nat64;
  failed_timestamp_seconds : nat64;
  reject_cost_e8s : nat64;
  derived_proposal_information : opt DerivedProposalInformation;
  latest_tally : opt Tally;
  reward_status : int32;
  decided_timestamp_seconds : nat64;
  proposal : opt Proposal;
  proposer : opt NeuronId;
  executed_timestamp_seconds : nat64;
  total_potential_voting_power : opt nat64;
};

type RegisterVote = record {
  vote : int32;
  proposal : opt ProposalId;
};

type RemoveHotKey = record {
  hot_key_to_remove : opt principal;
};

type RestoreAgingNeuronGroup = record {
  count : opt nat64;
  previous_total_stake_e8s : opt nat64;
  current_total_stake_e8s : opt nat64;
  group_type : int32;
};

type RestoreAgingSummary = record {
  groups : vec RestoreAgingNeuronGroup;
  timestamp_seconds : opt nat64;
};

type Result = variant {
  Ok;
  Err : GovernanceError;
};

type Result_1 = variant {
  Error : GovernanceError;
  NeuronId : NeuronId;
};

type Result_10 = variant {
  Ok : Ok_1;
  Err : GovernanceError;
};

type Result_2 = variant {
  Ok : Neuron;
  Err : GovernanceError;
};

type Result_3 = variant {
  Ok : GovernanceCachedMetrics;
  Err : GovernanceError;
};

type Result_4 = variant {
  Ok : MonthlyNodeProviderRewards;
  Err : GovernanceError;
};

type Result_5 = variant {
  Ok : NeuronInfo;
  Err : GovernanceError;
};

type Result_6 = variant {
  Ok : Ok;
  Err : GovernanceError;
};

type Result_7 = variant {
  Ok : NodeProvider;
  Err : GovernanceError;
};

type Result_8 = variant {
  Committed : Committed;
  Aborted : record {};
};

type Result_9 = variant {
  Committed : Committed_1;
  Aborted : record {};
};

type RewardEvent = record {
  rounds_since_last_distribution : opt nat64;
  day_after_genesis : nat64;
  actual_timestamp_seconds : nat64;
  total_available_e8s_equivalent : nat64;
  latest_round_available_e8s_equivalent : opt nat64;
  distributed_e8s_equivalent : nat64;
  settled_proposals : vec ProposalId;
};

type RewardMode = variant {
  RewardToNeuron : RewardToNeuron;
  RewardToAccount : RewardToAccount;
};

type RewardNodeProvider = record {
  node_provider : opt NodeProvider;
  reward_mode : opt RewardMode;
  amount_e8s : nat64;
};

type RewardNodeProviders = record {
  use_registry_derived_rewards : opt bool;
  rewards : vec RewardNodeProvider;
};

type RewardToAccount = record {
  to_account : opt AccountIdentifier;
};

type RewardToNeuron = record {
  dissolve_delay_seconds : nat64;
};

type SetDefaultFollowees = record {
  default_followees : vec record { int32; Followees };
};

type SetDissolveTimestamp = record {
  dissolve_timestamp_seconds : nat64;
};

type SetOpenTimeWindowRequest = record {
  open_time_window : opt TimeWindow;
};

type SetSnsTokenSwapOpenTimeWindow = record {
  request : opt SetOpenTimeWindowRequest;
  swap_canister_id : opt principal;
};

type SetVisibility = record {
  visibility : opt int32;
};

type SettleCommunityFundParticipation = record {
  result : opt Result_8;
  open_sns_token_swap_proposal_id : opt nat64;
};

type SettleNeuronsFundParticipationRequest = record {
  result : opt Result_9;
  nns_proposal_id : opt nat64;
};

type SettleNeuronsFundParticipationResponse = record {
  result : opt Result_10;
};

type Spawn = record {
  percentage_to_spawn : opt nat32;
  new_controller : opt principal;
  nonce : opt nat64;
};

type SpawnResponse = record {
  created_neuron_id : opt NeuronId;
};

type Split = record {
  amount_e8s : nat64;
  memo : opt nat64;
};

type StakeMaturity = record {
  percentage_to_stake : opt nat32;
};

type StakeMaturityResponse = record {
  maturity_e8s : nat64;
  staked_maturity_e8s : nat64;
};

type StopOrStartCanister = record {
  action : opt int32;
  canister_id : opt principal;
};

type SwapBackgroundInformation = record {
  ledger_index_canister_summary : opt CanisterSummary;
  fallback_controller_principal_ids : vec principal;
  ledger_archive_canister_summaries : vec CanisterSummary;
  ledger_canister_summary : opt CanisterSummary;
  swap_canister_summary : opt CanisterSummary;
  governance_canister_summary : opt CanisterSummary;
  root_canister_summary : opt CanisterSummary;
  dapp_canister_summaries : vec CanisterSummary;
};

type SwapDistribution = record {
  total : opt Tokens;
};

type SwapParameters = record {
  minimum_participants : opt nat64;
  neurons_fund_participation : opt bool;
  duration : opt Duration;
  neuron_basket_construction_parameters : opt NeuronBasketConstructionParameters;
  confirmation_text : opt text;
  maximum_participant_icp : opt Tokens;
  minimum_icp : opt Tokens;
  minimum_direct_participation_icp : opt Tokens;
  minimum_participant_icp : opt Tokens;
  start_time : opt GlobalTimeOfDay;
  maximum_direct_participation_icp : opt Tokens;
  maximum_icp : opt Tokens;
  neurons_fund_investment_icp : opt Tokens;
  restricted_countries : opt Countries;
};

type SwapParticipationLimits = record {
  min_participant_icp_e8s : opt nat64;
  max_participant_icp_e8s : opt nat64;
  min_direct_participation_icp_e8s : opt nat64;
  max_direct_participation_icp_e8s : opt nat64;
};

type Tally = record {
  no : nat64;
  yes : nat64;
  total : nat64;
  timestamp_seconds : nat64;
};

type TimeWindow = record {
  start_timestamp_seconds : nat64;
  end_timestamp_seconds : nat64;
};

type Tokens = record {
  e8s : opt nat64;
};

type UpdateCanisterSettings = record {
  canister_id : opt principal;
  settings : opt CanisterSettings;
};

type UpdateNodeProvider = record {
  reward_account : opt AccountIdentifier;
};

type VotingRewardParameters = record {
  reward_rate_transition_duration : opt Duration;
  initial_reward_rate : opt Percentage;
  final_reward_rate : opt Percentage;
};

type WaitForQuietState = record {
  current_deadline_timestamp_seconds : nat64;
};

type XdrConversionRate = record {
  xdr_permyriad_per_icp : opt nat64;
  timestamp_seconds : opt nat64;
};

type MaturityDisbursement = record {
  amount_e8s : opt nat64;
  timestamp_of_disbursement_seconds : opt nat64;
  finalize_disbursement_timestamp_seconds : opt nat64;
  account_to_disburse_to : opt Account;
  account_identifier_to_disburse_to : opt AccountIdentifier;
};

// A topic that can be followed. It is almost the same as the topic on the
// proposal, except that the `CatchAll` is a special value and following on this
// `topic` will let the neuron follow the votes on all topics except for
// Governance and SnsAndCommunityFund.
type TopicToFollow = variant {
  CatchAll;
  NeuronManagement;
  ExchangeRate;
  NetworkEconomics;
  Governance;
  NodeAdmin;
  ParticipantManagement;
  SubnetManagement;
  Kyc;
  NodeProviderRewards;
  IcOsVersionDeployment;
  IcOsVersionElection;
  SnsAndCommunityFund;
  ApiBoundaryNodeManagement;
  SubnetRental;
  ApplicationCanisterManagement;
  ProtocolCanisterManagement;
  ServiceNervousSystemManagement;
};

type ListNeuronVotesRequest = record {
  // The neuron id for which the voting history will be returned. Currently, the voting history is
  // only recorded for known neurons.
  neuron_id : opt NeuronId;
  // Only fetch the voting history for proposal whose id `< before_proposal`. This can be used as a
  // pagination token - pass the minimum proposal id as `before_proposal` for the next page.
  before_proposal : opt ProposalId;
  // The maximum number of votes to fetch. The maximum number allowed is 500, and 500 will be used
  // if is set as either null or > 500.
  limit : opt nat64;
};

type ListNeuronVotesResponse = variant {
  Ok : record {
    votes : opt vec NeuronVote;
    // All the proposals before this id is "finalized", which means if a proposal before this id
    // does not exist in the votes, it will never appear in the voting history, either because the
    // neuron is not eligible to vote on the proposal, or the neuron is not a known neuron at the
    // time of the proposal creation. Therefore, if a client syncs the entire voting history of a
    // certain neuron and store `all_finalized_before_proposal`, it doesn't need to start from
    // scratch the next time - it can stop as soon as they have seen any votes 
    // `< all_finalized_before_proposal`.
    all_finalized_before_proposal : opt ProposalId;
  };
  Err : GovernanceError;
};

type NeuronVote = record {
  proposal_id : opt ProposalId;
  // The vote of the neuron on the specific proposal id.
  vote : opt Vote;
};

type Vote = variant {
  // Abstentions are recorded as Unspecified.
  Unspecified;
  Yes;
  No;
};

type SelfDescribingProposalAction = record {
  type_name : opt text;
  type_description : opt text;
  value : opt SelfDescribingValue;
};

type SelfDescribingValue = variant {
  Blob : blob;
  Text : text;
  Nat : nat;
  Int : int;
  Array : vec SelfDescribingValue;
  Map : vec record { text; SelfDescribingValue };
};

type GetPendingProposalsRequest = record {
  return_self_describing_action : opt bool;
}

service : (Governance) -> {
  claim_gtc_neurons : (principal, vec NeuronId) -> (Result);
  claim_or_refresh_neuron_from_account : (ClaimOrRefreshNeuronFromAccount) -> (
      ClaimOrRefreshNeuronFromAccountResponse,
    );
  get_build_metadata : () -> (text) query;
  get_full_neuron : (nat64) -> (Result_2) query;
  get_full_neuron_by_id_or_subaccount : (NeuronIdOrSubaccount) -> (
      Result_2,
    ) query;
  get_latest_reward_event : () -> (RewardEvent) query;
  get_metrics : () -> (Result_3) query;
  get_monthly_node_provider_rewards : () -> (Result_4);
  get_most_recent_monthly_node_provider_rewards : () -> (
      opt MonthlyNodeProviderRewards,
    ) query;
  get_network_economics_parameters : () -> (NetworkEconomics) query;
  get_neuron_ids : () -> (vec nat64) query;
  get_neuron_index: (GetNeuronIndexRequest) -> (GetNeuronIndexResult) query;
  get_neuron_info : (nat64) -> (Result_5) query;
  get_neuron_info_by_id_or_subaccount : (NeuronIdOrSubaccount) -> (
      Result_5,
    ) query;
  get_neurons_fund_audit_info : (GetNeuronsFundAuditInfoRequest) -> (
      GetNeuronsFundAuditInfoResponse,
    ) query;
  get_node_provider_by_caller : (null) -> (Result_7) query;
  get_pending_proposals : (opt GetPendingProposalsRequest) -> (vec ProposalInfo) query;
  get_proposal_info : (nat64) -> (opt ProposalInfo) query;
  get_restore_aging_summary : () -> (RestoreAgingSummary) query;
  list_known_neurons : () -> (ListKnownNeuronsResponse) query;
  list_neurons : (ListNeurons) -> (ListNeuronsResponse) query;
  list_node_provider_rewards : (ListNodeProviderRewardsRequest) -> (
      ListNodeProviderRewardsResponse,
    ) query;
  list_node_providers : () -> (ListNodeProvidersResponse) query;
  list_proposals : (ListProposalInfoRequest) -> (ListProposalInfoResponse) query;
  list_neuron_votes : (ListNeuronVotesRequest) -> (ListNeuronVotesResponse) query;
  manage_neuron : (ManageNeuronRequest) -> (ManageNeuronResponse);
  settle_community_fund_participation : (SettleCommunityFundParticipation) -> (
      Result,
    );
  settle_neurons_fund_participation : (
      SettleNeuronsFundParticipationRequest,
    ) -> (SettleNeuronsFundParticipationResponse);
  simulate_manage_neuron : (ManageNeuronRequest) -> (ManageNeuronResponse);
  transfer_gtc_neuron : (NeuronId, NeuronId) -> (Result);
  update_node_provider : (UpdateNodeProvider) -> (Result);
}
"""

class Governance(Canister):
    def __init__(self, agent):
        super().__init__(agent, "rrkah-fqaaa-aaaaa-aaaaq-cai", governance_did)
