syntax = "proto3";

package xyz.aspens.arborter_config.v1;

import "attestation.proto";

option optimize_for = SPEED;

// The Configuration service definition
service ConfigService {
  // rpc service to set the admin address
  rpc UpdateAdmin(UpdateAdminRequest) returns (UpdateAdminResponse) {}
  // rpc service to get pre-encoded calldata for deploying a trading instance
  rpc GetDeployCalldata(GetDeployCalldataRequest) returns (GetDeployCalldataResponse) {}
  // rpc service to deploy a trading instance on the base and quote chains
  rpc DeployContract(DeployContractRequest) returns (DeployContractResponse) {}
  // rpc service to set a chain in the configuration
  rpc SetChain(SetChainRequest) returns (SetChainResponse) {}
  // rpc service to set a new token to trade
  rpc SetToken(SetTokenRequest) returns (SetTokenResponse) {}
  // rpc service to set a new market to trade
  rpc SetMarket(SetMarketRequest) returns (SetMarketResponse) {}
  // rpc service to set a new trading instance
  rpc SetTradeContract(SetTradeContractRequest) returns (SetTradeContractResponse) {}
  // rpc service to set an instance's operator fee (recipient + bps). The
  // arborter submits the on-chain setOperatorFee/set_operator_fee as the
  // instance's operator_admin (the arborter signer, while unrotated).
  rpc SetOperatorFee(SetOperatorFeeRequest) returns (SetOperatorFeeResponse) {}
  // rpc service to rotate an instance's operator_admin key. After rotation the
  // new admin (not the arborter) gates operator-fee changes.
  rpc SetOperatorAdmin(SetOperatorAdminRequest) returns (SetOperatorAdminResponse) {}
  // rpc service to get the configuration
  rpc GetConfig(GetConfigRequest) returns (GetConfigResponse) {}
  // rpc service to get version information
  rpc GetVersion(Empty) returns (VersionInfo) {}
  // rpc service to get the TPM signer public key
  rpc GetSignerPublicKey(GetSignerPublicKeyRequest) returns (GetSignerPublicKeyResponse);
  // rpc service to get TEE attestation from the signer
  rpc GetAttestation(xyz.aspens.attestation.v1.GetAttestationRequest) returns (xyz.aspens.attestation.v1.GetAttestationResponse);
  // rpc service to delete a market
  rpc DeleteMarket(DeleteMarketRequest) returns (DeleteMarketResponse) {}
  // rpc service to delete a token
  rpc DeleteToken(DeleteTokenRequest) returns (DeleteTokenResponse) {}
  // rpc service to delete a chain
  rpc DeleteChain(DeleteChainRequest) returns (DeleteChainResponse) {}
  // rpc service to delete a trading instance
  rpc DeleteTradeContract(DeleteTradeContractRequest) returns (DeleteTradeContractResponse) {}
}

message UpdateAdminRequest {
  // The address to set for admin management operations
  string admin_address = 1;
}

message UpdateAdminResponse {
  // The address that has been set for admin management operations
  string admin_address = 1;
}

message GetDeployCalldataRequest {
  // The name of the chain to deploy the instance on. e.g. base-sepolia
  string chain_network = 1;
  // Fee in basis points for the trading instance (e.g., 100 = 1%)
  uint32 fee_bps = 2;
}

message GetDeployCalldataResponse {
  // The factory contract address to call
  string factory_address = 1;
  // The ABI-encoded calldata for createInstance(signer, feeBps)
  // The signer address is pre-populated with the correct instance signer
  bytes calldata = 2;
  // The instance signer address that will own the deployed contract
  string instance_signer_address = 3;
  // The chain ID for transaction construction
  uint32 chain_id = 4;
}

message DeployContractRequest {
  // The name of the chain to deploy the instance on. e.g. base-sepolia
  string chain_network = 1;
  // The signed transaction hash of the createInstance function call.
  // Required for EVM (admin signs+broadcasts the tx locally, then asks
  // arborter to confirm + register the result). Empty / omitted for Solana,
  // where arborter signs and submits server-side using its own signer
  // (the only key that can satisfy the factory's `has_one = owner` check).
  string tx_hash = 2;
  // Refuse the deploy if the chain already has a trade_contract
  // registered. Defaults to false (refuse). Set to true to overwrite the
  // existing registration — note that previously deposited balances live on
  // the *old* contract/instance and become orphaned.
  bool force = 3;
  // Trading fee in basis points. Used by the Solana server-side path,
  // which constructs the create_instance ix here (so it needs the fee at
  // call time). Ignored by the EVM path — for EVM the fee was baked into
  // the calldata returned by GetDeployCalldata and signed by the admin.
  uint32 fee_bps = 4;
}

message DeployContractResponse {
  // The address that the instance is deployed to on the specified chain.
  // Hex (0x-prefixed) for EVM, base58 for Solana.
  string contract_address = 1;
  // Receipt for the on-chain operation. Populated for the Solana
  // server-side path (base58 signature). Empty for EVM, where the admin
  // already has the tx_hash they submitted.
  string tx_signature = 2;
}

message SetChainRequest {
  // The chain to set
  Chain chain = 1;
}

message SetChainResponse {
  // Indicates if the chain was set successfully
  bool success = 1;
  // The configuration object
  Configuration config = 2;
}

message SetTokenRequest {
  // The name of the chain to set the token on. e.g. base-sepolia
  string chain_network = 1;
  // The token to set
  Token token = 2;
}

message SetTokenResponse {
  // Indicates if the token was set successfully
  bool success = 1;
  // The configuration object
  Configuration config = 2;
}

message SetMarketRequest {
  // The base chain network
  string base_chain_network = 1;
  // The quote chain network
  string quote_chain_network = 2;
  // The base chain token symbol
  string base_chain_token_symbol = 3;
  // The quote chain token symbol
  string quote_chain_token_symbol = 4;
  // The base chain token address
  string base_chain_token_address = 5;
  // The quote chain token address
  string quote_chain_token_address = 6;
  // The base chain token decimals
  int32 base_chain_token_decimals = 7;
  // The quote chain token decimals
  int32 quote_chain_token_decimals = 8;
  // The pair decimals (this is chosen by the stack admin)
  int32 pair_decimals = 9;
}

message SetMarketResponse {
  // Indicates if the market was set successfully
  bool success = 1;
  // The configuration object
  Configuration config = 2;
}

message SetTradeContractRequest {
  // The chain address of the trading instance
  string address = 1;
  // The chain network to associate the trading instance with
  string chain_network = 2;
}

message SetTradeContractResponse {
  // The created trading instance
  TradeContract trade_contract = 1;
}
message SetOperatorFeeRequest {
  // The chain network whose instance to update. e.g. base-sepolia
  string chain_network = 1;
  // Operator-fee recipient address (0x-hex for EVM, base58 for Solana).
  string recipient = 2;
  // Operator fee in basis points. Combined with maintenance bps the contract
  // rejects a total above the bps denominator (10000).
  uint32 bps = 3;
}
message SetOperatorFeeResponse {
  // On-chain tx hash / signature for the setOperatorFee call (0x-hex EVM,
  // base58 Solana).
  string tx_signature = 1;
}
message SetOperatorAdminRequest {
  // The chain network whose instance to update.
  string chain_network = 1;
  // The new operator_admin key (0x-hex for EVM, base58 for Solana).
  string new_admin = 2;
}
message SetOperatorAdminResponse {
  // On-chain tx hash / signature for the setOperatorAdmin call.
  string tx_signature = 1;
}

// Request message for the service
message GetConfigRequest {
  // Add optional filters in the future (e.g., chain or market name)
}
message GetConfigResponse {
  // The configuration object
  Configuration config = 1;
}

// The top-level response containing chains and markets
message Configuration {
  // List of supported chains
  repeated Chain chains = 1;
  // List of supported markets
  repeated Market markets = 2;
}

// Represents the trading instance details
message TradeContract {
  // Optional: For non-EVM chains like Hedera, Solana, etc.
  optional string contract_id = 1;
  // The chain address of the trading instance
  string address = 2;
}

// Represents a single blockchain network
message Chain {
  // The architecture of the chain (e.g., EVM, Hedera)
  string architecture = 1;
  // The canonical name of the chain (e.g., 'Ethereum Mainnet' | 'Hedera Testnet')
  string canonical_name = 2;
  // The chain network (e.g., op-mainnet, hedera-testnet)
  string network = 3;
  // The chain ID (e.g., Ethereum = 1)
  uint32 chain_id = 4;
  // Pubkey address of the signer of the deployed trading instance
  string instance_signer_address = 5;
  // Optional: URL to the chain explorer
  optional string explorer_url = 6;
  // The RPC URL for the chain
  string rpc_url = 7;
  // The address of the factory contract on this chain. This is the address to call to deploy a new trading instance
  string factory_address = 8;
  // The trading instance details
  TradeContract trade_contract = 10;
  // Mapping of token symbols to token details
  map<string, Token> tokens = 11;
}

// Represents a market with a base- and quote- chain token pair
message Market {
  // The market name, e.g. 'Base Sepolia USDC - OP Sepolia USDC'
  string name = 1;
  // The base chain, e.g. 'base-sepolia'
  string base_chain_network = 2;
  // The quote chain, e.g. 'op-sepolia'
  string quote_chain_network = 3;
  /// The token symbol for the base chain
  string base_chain_token_symbol = 4;
  /// The token symbol for the quote chain
  string quote_chain_token_symbol = 5;
  // The base chain token decimals
  int32 base_chain_token_decimals = 6;
  // The quote chain token decimals
  int32 quote_chain_token_decimals = 7;
  // The pair decimals (this is chosen by the stack admin)
  int32 pair_decimals = 8;
  // Identity the market: concat(base_network "::" token_address "::" quote_network "::" token_address)
  string market_id = 9;
}

// Represents a single token
message Token {
  // The name of the token
  string name = 1;
  // The symbol of the token
  string symbol = 2;
  // The chain address of the token contract
  string address = 3;
  // Optional: for networks that use IDs (e.g., Hedera)
  optional string token_id = 4;
  // The number of decimal places the token is defined with
  uint32 decimals = 5;
}

// Request to get signer public key(s)
message GetSignerPublicKeyRequest {
  // Optional: Request specific chain by network name
  // If omitted, returns all chains
  optional string chain_network = 1;
}

// Single chain's public key information
message ChainPublicKey {
  // The chain ID
  uint32 chain_id = 1;
  // The chain network name (e.g., "anvil-1", "base-sepolia")
  string chain_network = 2;
  // The signer's public key (address) for this chain
  string public_key = 3;
}

// Response with public keys per chain
message GetSignerPublicKeyResponse {
  // Map of chain network name to public key info
  map<string, ChainPublicKey> chain_keys = 1;
}

// Delete market request
message DeleteMarketRequest {
  // The market ID to delete
  string market_id = 1;
}

// Delete market response
message DeleteMarketResponse {
  // Indicates if the market was deleted successfully
  bool success = 1;
  // The configuration object after deletion
  Configuration config = 2;
}

// Delete token request
message DeleteTokenRequest {
  // The chain network where the token exists
  string chain_network = 1;
  // The token symbol to delete
  string token_symbol = 2;
}

// Delete token response
message DeleteTokenResponse {
  // Indicates if the token was deleted successfully
  bool success = 1;
  // The configuration object after deletion
  Configuration config = 2;
}

// Delete chain request
message DeleteChainRequest {
  // The chain network to delete
  string chain_network = 1;
}

// Delete chain response
message DeleteChainResponse {
  // Indicates if the chain was deleted successfully
  bool success = 1;
  // The configuration object after deletion
  Configuration config = 2;
}

// Delete trading instance request
message DeleteTradeContractRequest {
  // The chain network to delete the trading instance from
  string chain_network = 1;
}

// Delete trading instance response
message DeleteTradeContractResponse {
  // Indicates if the trading instance was deleted successfully
  bool success = 1;
  // The configuration object after deletion
  Configuration config = 2;
}

message Empty {}

// Version information in vergen style
message VersionInfo {
  // The version of the application (e.g., "1.0.0")
  string version = 1;
  // The git commit hash
  string git_commit_hash = 2;
  // The git commit date
  string git_commit_date = 3;
  // The git branch name
  string git_branch = 4;
  // The build timestamp
  string build_timestamp = 5;
  // The target triple
  string target_triple = 6;
  // The rustc version used to build
  string rustc_version = 7;
  // The cargo features enabled
  repeated string cargo_features = 8;
}
