syntax = "proto3";
package forge_abi;

import "google/protobuf/any.proto";
import "vendor.proto";
import "enum.proto";
import "type.proto";
import "state.proto";
import "tx.proto";
import "trace_type.proto";

// Request / Response message definition

// create_tx(itx, wallet, token)
message RequestCreateTx {
  google.protobuf.Any itx = 1;
  string from = 2;
  uint64 nonce = 3;
  WalletInfo wallet = 4;
  string token = 5;
}

message ResponseCreateTx {
  StatusCode code = 1;
  Transaction tx = 2;
}

// multisig(tx, wallet, token)
message RequestMultisig {
	Transaction tx = 1;
	// extra data for multisig
	google.protobuf.Any data = 2;
  WalletInfo wallet = 3;
	string token = 4;

}

message ResponseMultisig {
  StatusCode code = 1;
  Transaction tx = 2;
}

// send_tx(tx, wallet, token, commit \\ false)
message RequestSendTx {
  Transaction tx = 1;
  WalletInfo wallet = 2;
  string token = 3;
  bool commit = 4;
}

message ResponseSendTx {
  StatusCode code = 1;
  string hash = 2;
}

// get_tx(hash)
message RequestGetTx { string hash = 1; }

message ResponseGetTx {
  StatusCode code = 1;
  TransactionInfo info = 2;
}

// get_block(height)
message RequestGetBlock { uint64 height = 1; }

message ResponseGetBlock {
  StatusCode code = 1;
  BlockInfo block = 2;
}

message RequestGetBlocks {
  PageInput paging = 1;
  uint64 min_height = 2;
  uint64 max_height = 3;
  bool empty_excluded = 4;
}

message ResponseGetBlocks {
  StatusCode code = 1;
  PageInfo page = 2;
  repeated BlockInfo blocks = 3;
}

// create_wallet(moniker, passphrase): create an account locally
message RequestCreateWallet {
  string passphrase = 1;
  WalletType type = 2;
  string moniker = 3;
}

message ResponseCreateWallet {
  StatusCode code = 1;
  string token = 2;
  WalletInfo wallet = 3;
}

// load_wallet(address, passphrase): load account to memory with given
// passphrase
message RequestLoadWallet {
  string address = 1;
  string passphrase = 2;
}

message ResponseLoadWallet {
  StatusCode code = 1;
  string token = 2;
  WalletInfo wallet = 3;
}

// recover_wallet(data, passphrase): recover to a keystore with given
// passphrase. data could be seed words or bytes of secret key.
message RequestRecoverWallet {
  bytes data = 1;
  WalletType type = 2;
  string passphrase = 3;
  string moniker = 4;
}

message ResponseRecoverWallet {
  StatusCode code = 1;
  string token = 2;
  WalletInfo wallet = 3;
}

// list_wallet(): list accounts stored in this node
message RequestListWallet {}

message ResponseListWallet {
  StatusCode code = 1;
  string address = 2;
}

// remove_wallet(hash): remove account by hash for this node
message RequestRemoveWallet { string address = 1; }

message ResponseRemoveWallet { StatusCode code = 1; }

message RequestDeclareNode { bool validator = 1; }

message ResponseDeclareNode {
  StatusCode code = 1;
  WalletInfo wallet = 3;
}

// get_account_state(address, key): retrieve the current state from a list of
// wallet addresses, return the value of the key. If key is omitted, return
// entire account states
message RequestGetAccountState {
  string address = 1;
  repeated string keys = 2;
  uint64 height = 3;
}

message ResponseGetAccountState {
  StatusCode code = 1;
  AccountState state = 2;
}

message RequestGetAssetState {
  string address = 1;
  repeated string keys = 2;
  uint64 height = 3;
}

message ResponseGetAssetState {
  StatusCode code = 1;
  AssetState state = 2;
}

message RequestGetStakeState {
  string address = 1;
  repeated string keys = 2;
  uint64 height = 3;
}

message ResponseGetStakeState {
  StatusCode code = 1;
  StakeState state = 2;
}

// get_forge_state(key): retrieve Forge state by key. If key is omitted, return
// entire Forge state
message RequestGetForgeState {
  repeated string keys = 1;
  uint64 height = 3;
}

message ResponseGetForgeState {
  StatusCode code = 1;
  ForgeState state = 2;
}

// store_file(chunk): store a piece of data into ipfs, return its hash address
message RequestStoreFile { bytes chunk = 1; }

message ResponseStoreFile {
  StatusCode code = 1;
  string hash = 2;
}

// load_file(hash): load a hash address from ipfs and return the file content
message RequestLoadFile { string hash = 1; }

message ResponseLoadFile {
  StatusCode code = 1;
  bytes chunk = 2;
}

// pin_file(hash): pin a hash address into ipfs, return ok if success
message RequestPinFile { string hash = 1; }

message ResponsePinFile { StatusCode code = 1; }

// get_chain_info(): retrieve the current chain information
message RequestGetChainInfo {}

message ResponseGetChainInfo {
  StatusCode code = 1;
  ChainInfo info = 2;
}

// get_node_info(): retrieve the current node information
message RequestGetNodeInfo {}

message ResponseGetNodeInfo {
  StatusCode code = 1;
  NodeInfo info = 2;
}

// search(term): retrieve related transactions by a search term (prefix match)
message RequestSearch {
  string key = 1;
  string value = 2;
}

message ResponseSearch {
  StatusCode code = 1;
  repeated TransactionInfo txs = 2;
}

message RequestGetUnconfirmedTxs { uint32 limit = 1; }

message ResponseGetUnconfirmedTxs {
  StatusCode code = 1;
  UnconfirmedTxs unconfirmed_txs = 2;
}

message RequestGetNetInfo {}

message ResponseGetNetInfo {
  StatusCode code = 1;
  NetInfo net_info = 2;
}

message RequestGetValidatorsInfo {}

message ResponseGetValidatorsInfo {
  StatusCode code = 1;
  ValidatorsInfo validators_info = 2;
}

// event subscription

// filter could be: value.header.height > 10086 and value.byzantine_validators
// != []
message RequestSubscribe {
  TopicType type = 1;
  string filter = 2;
}

message ResponseSubscribe {
  StatusCode code = 1;
  oneof value {
    string topic = 2;
    Transaction transfer = 3;
    Transaction account_migrate = 4;
    Transaction confirm = 5;
    Transaction create_asset = 6;
    Transaction exchange = 7;
    Transaction revoke = 8;

    abci_vendor.RequestBeginBlock begin_block = 16;
    abci_vendor.RequestEndBlock end_block = 17;

    Transaction declare = 19;
    Transaction update_asset = 20;
    Transaction consensus_upgrade = 21;
    Transaction declare_file = 22;
    Transaction sys_upgrade = 23;
    Transaction stake = 24;

    Transaction account_state = 129;
    Transaction asset_state = 130;
    Transaction forge_state = 131;
    Transaction stake_state = 132;
  }
}

message RequestUnsubscribe { string topic = 1; }

message ResponseUnsubscribe { StatusCode code = 1; }

// get config
message RequestGetConfig {}
message ResponseGetConfig {
  StatusCode code = 1;
  string config = 2;
}

message ByDay {
  string start_date = 1;
  string end_date = 2;
}

message ByHour {
  string date = 1;
}


message RequestGetForgeStatistics {
  oneof value {
    ByDay day_info = 1;
    ByHour date = 2;
  }
}

message ResponseGetForgeStatistics {
  StatusCode code = 1;
  ForgeStatistics forge_statistics = 2;
}

message RequestListTransactions {
  PageInput paging = 1;
  TimeFilter time_filter = 2;
  AddressFilter address_filter = 3;
  TypeFilter type_filter = 4;
}

message ResponseListTransactions {
  StatusCode code = 1;
  PageInfo page = 2;
  repeated IndexedTransaction transactions = 3;
}

message RequestGetAssetAddress {
  string sender_address = 1;
  CreateAssetTx itx = 2;
  WalletType wallet_type = 3;
}

message ResponseGetAssetAddress {
  StatusCode code = 1;
  string asset_address = 2;
}

message RequestSignData {
  bytes data = 1;
  WalletInfo wallet = 2;
  string token = 3;
}

message ResponseSignData {
  StatusCode code = 1;
  bytes signature = 2;
}

message RequestGetAssets {
  PageInput paging = 1;
  string owner_address = 2;
}

message ResponseGetAssets {
  StatusCode code = 1;
  PageInfo page = 2;
  repeated IndexedAssetState assets = 3;
}

message RequestGetStakes {
  PageInput paging = 1;
  AddressFilter address_filter = 2;
}

message ResponseGetStakes {
  StatusCode code = 1;
  PageInfo page = 2;
  repeated IndexedStakeState stakes = 3;
}

message RequestGetTopAccounts {
  PageInput paging = 1;
}

message ResponseGetTopAccounts {
  StatusCode code = 1;
  PageInfo page = 2;
  repeated IndexedAccountState accounts = 3;
}

message RequestListAssetTransactions {
  PageInput paging = 1;
  string address = 2;
}

message ResponseListAssetTransactions {
  StatusCode code = 1;
  PageInfo page = 2;
  repeated IndexedTransaction transactions = 3;
}

message RequestListBlocks {
  PageInput paging = 1;
  string proposer = 2;
  TimeFilter time_filter = 3;
  HeightFilter height_filter = 4;
  NumTxsFilter num_txs_filter = 5;
  NumInvalidTxsFilter num_invalid_txs_filter = 6;
}

message ResponseListBlocks {
  StatusCode code = 1;
  PageInfo page = 2;
  repeated IndexedBlock blocks = 3;
}

message RequestListAssets {
  PageInput paging = 1;
  string owner_address = 2;
}

message ResponseListAssets {
  StatusCode code = 1;
  PageInfo page = 2;
  IndexedAccountState account = 3;
  repeated IndexedAssetState assets = 4;
}

message RequestGetHealthStatus {}

message ResponseGetHealthStatus {
  StatusCode code = 1;
  HealthStatus health_status = 2;
}
