syntax = "proto3";
package provlabs.vault.v1;

import "cosmos/base/query/v1beta1/pagination.proto";
import "cosmos/base/v1beta1/coin.proto";
import "cosmos_proto/cosmos.proto";
import "gogoproto/gogo.proto";
import "google/api/annotations.proto";
import "google/protobuf/timestamp.proto";
import "provlabs/vault/v1/params.proto";
import "provlabs/vault/v1/vault.proto";

option go_package = "github.com/provlabs/vault/types";

// Query is the service for the vault module's query endpoints.
service Query {
  // Vaults returns a paginated list of all vaults.
  rpc Vaults(QueryVaultsRequest) returns (QueryVaultsResponse) {
    option (google.api.http).get = "/vault/v1/vaults";
  }

  // Vault returns the configuration and state of a specific vault.
  rpc Vault(QueryVaultRequest) returns (QueryVaultResponse) {
    option (google.api.http).get = "/vault/v1/vaults/{id}";
  }

  // EstimateSwapIn estimates the amount of shares that would be received for a given amount of underlying assets.
  rpc EstimateSwapIn(QueryEstimateSwapInRequest) returns (QueryEstimateSwapInResponse) {
    option (google.api.http).get = "/vault/v1/vaults/{vault_address}/estimate_swap_in";
  }

  // EstimateSwapOut estimates the amount of underlying assets that would be received for a given amount of shares.
  rpc EstimateSwapOut(QueryEstimateSwapOutRequest) returns (QueryEstimateSwapOutResponse) {
    option (google.api.http).get = "/vault/v1/vaults/{vault_address}/estimate_swap_out";
  }

  // PendingSwapOuts returns a paginated list of all pending swap outs.
  rpc PendingSwapOuts(QueryPendingSwapOutsRequest) returns (QueryPendingSwapOutsResponse) {
    option (google.api.http).get = "/vault/v1/pending_swap_outs";
  }

  // VaultPendingSwapOuts returns a paginated list of all pending swap outs for a specific vault.
  rpc VaultPendingSwapOuts(QueryVaultPendingSwapOutsRequest) returns (QueryVaultPendingSwapOutsResponse) {
    option (google.api.http).get = "/vault/v1/vaults/{id}/pending_swap_outs";
  }

  // Params returns the current module parameters.
  rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {
    option (google.api.http).get = "/vault/v1/params";
  }

  // VaultNavs returns a paginated list of all internal NAV entries for a vault.
  rpc VaultNavs(QueryVaultNavsRequest) returns (QueryVaultNavsResponse) {
    option (google.api.http).get = "/vault/v1/vaults/{id}/navs";
  }

  // NavValue returns a single internal NAV entry for a vault and denom.
  rpc NavValue(QueryNavValueRequest) returns (QueryNavValueResponse) {
    // denom uses a multi-segment capture so denominations containing "/"
    // (e.g. "ibc/..." or "factory/...") route correctly.
    option (google.api.http).get = "/vault/v1/vaults/{id}/navs/{denom=**}";
  }

  // VaultPayment returns a single pending exchange-module payment targeting a vault,
  // identified by the payment's source account and external id.
  rpc VaultPayment(QueryVaultPaymentRequest) returns (QueryVaultPaymentResponse) {
    option (google.api.http).get = "/vault/v1/vaults/{id}/payment";
  }

  // VaultPayments returns a paginated list of all pending exchange-module payments
  // targeting a vault.
  rpc VaultPayments(QueryVaultPaymentsRequest) returns (QueryVaultPaymentsResponse) {
    option (google.api.http).get = "/vault/v1/vaults/{id}/payments";
  }
}

// QueryVaultPendingSwapOutsRequest is the request message for the Query/VaultPendingSwapOuts endpoint.
message QueryVaultPendingSwapOutsRequest {
  // id is the bech32 address of the vault or the vault's share denom to query.
  string id = 1;
  // pagination defines an optional pagination for the request.
  cosmos.base.query.v1beta1.PageRequest pagination = 2;
}

// QueryVaultPendingSwapOutsResponse is the response message for the Query/VaultPendingSwapOuts endpoint.
message QueryVaultPendingSwapOutsResponse {
  // pending_swap_outs is a list of all pending swap outs.
  repeated PendingSwapOutWithTimeout pending_swap_outs = 1 [(gogoproto.nullable) = false];
  // pagination defines the pagination in the response.
  cosmos.base.query.v1beta1.PageResponse pagination = 2;
}

// QueryPendingSwapOutsRequest is the request message for the Query/PendingSwapOuts endpoint.
message QueryPendingSwapOutsRequest {
  // pagination defines an optional pagination for the request.
  cosmos.base.query.v1beta1.PageRequest pagination = 1;
}

// QueryPendingSwapOutsResponse is the response message for the Query/PendingSwapOuts endpoint.
message QueryPendingSwapOutsResponse {
  // pending_swap_outs is a list of all pending swap outs.
  repeated PendingSwapOutWithTimeout pending_swap_outs = 1 [(gogoproto.nullable) = false];
  // pagination defines the pagination in the response.
  cosmos.base.query.v1beta1.PageResponse pagination = 2;
}

// PendingSwapOutWithTimeout is a pending swap out with its timeout.
message PendingSwapOutWithTimeout {
  // request_id is the unique identifier for the pending swap out request.
  uint64 request_id = 1;
  // pending_swap_out contains the details of the swap out request.
  PendingSwapOut pending_swap_out = 2 [(gogoproto.nullable) = false];
  // timeout is the time at which the pending swap out will expire if not processed.
  google.protobuf.Timestamp timeout = 3 [
    (gogoproto.stdtime) = true,
    (gogoproto.nullable) = false
  ];
}

// QueryVaultsRequest is the request message for the Query/Vaults endpoint.
message QueryVaultsRequest {
  // pagination defines an optional pagination for the request.
  cosmos.base.query.v1beta1.PageRequest pagination = 1;
}

// QueryVaultsResponse is the response message for the Query/Vaults endpoint.
message QueryVaultsResponse {
  // vaults is a list of all vaults.
  repeated VaultAccount vaults = 1 [(gogoproto.nullable) = false];
  // pagination defines the pagination in the response.
  cosmos.base.query.v1beta1.PageResponse pagination = 2;
}

// QueryVaultRequest is the request message for the Query/Vault endpoint.
message QueryVaultRequest {
  // id is the bech32 address of the vault or the vault's share denom to query.
  string id = 1;
}

// QueryVaultResponse is the response message for the Query/Vault endpoint.
message QueryVaultResponse {
  // vault is the requested vault.
  VaultAccount vault = 1 [(gogoproto.nullable) = false];
  // principal is the total amount of principal held in the vault's marker.
  AccountBalance principal = 2 [(gogoproto.nullable) = false];
  // reserves is the total amount of reserves held in the vault account for interest payments.
  AccountBalance reserves = 3 [(gogoproto.nullable) = false];
  // total_vault_value is the estimated total value of the vault in its
  // underlying asset. It includes current principal and estimated unpaid
  // interest (at query block height), but excludes reserves. The value is approximate and may differ
  // from the reconciled amount.
  cosmos.base.v1beta1.Coin total_vault_value = 4 [(gogoproto.nullable) = false];
}

// QueryEstimateSwapInRequest is the request message for the Query/EstimateSwapIn endpoint.
message QueryEstimateSwapInRequest {
  // vault_address is the bech32 address of the vault to query.
  string vault_address = 1;
  // assets is the amount of the underlying asset to swap in.
  cosmos.base.v1beta1.Coin assets = 2 [(gogoproto.nullable) = false];
}

// QueryEstimateSwapInResponse is the response message for the Query/EstimateSwapIn endpoint.
message QueryEstimateSwapInResponse {
  // assets is the estimated amount of shares that would be received.
  cosmos.base.v1beta1.Coin assets = 1 [(gogoproto.nullable) = false];
  // The block height when the estimate occurred.
  int64 height = 2;
  // The UTC block time when the estimate occurred.
  google.protobuf.Timestamp time = 3 [
    (gogoproto.stdtime) = true,
    (gogoproto.nullable) = false
  ];
}

// QueryEstimateSwapOutRequest is the request message for the Query/EstimateSwapOut endpoint.
message QueryEstimateSwapOutRequest {
  // vault_address is the bech32 address of the vault to query.
  string vault_address = 1;
  // shares is the amount of shares to swap out.
  string shares = 2;
  // redeem_denom previously selected the payout denom to estimate. The estimate
  // is always in the vault's underlying_asset; if set, this must equal
  // underlying_asset. Retained for wire compatibility with released clients.
  string redeem_denom = 3 [deprecated = true];
}

// QueryEstimateSwapOutResponse is the response message for the Query/EstimateSwapOut endpoint.
message QueryEstimateSwapOutResponse {
  // assets is the estimated amount of underlying assets that would be received.
  cosmos.base.v1beta1.Coin assets = 1 [(gogoproto.nullable) = false];
  // The block height when the estimate occurred.
  int64 height = 2;
  // The UTC block time when the estimate occurred.
  google.protobuf.Timestamp time = 3 [
    (gogoproto.stdtime) = true,
    (gogoproto.nullable) = false
  ];
}

// QueryParamsRequest is the request message for the Query/Params endpoint.
message QueryParamsRequest {}

// QueryParamsResponse is the response message for the Query/Params endpoint.
message QueryParamsResponse {
  // params defines the vault module parameters.
  Params params = 1 [(gogoproto.nullable) = false];
}

// QueryVaultNavsRequest is the request message for the Query/VaultNavs endpoint.
message QueryVaultNavsRequest {
  // id is the bech32 address of the vault or the vault's share denom to query.
  string id = 1;
  // pagination defines an optional pagination for the request.
  cosmos.base.query.v1beta1.PageRequest pagination = 2;
}

// QueryVaultNavsResponse is the response message for the Query/VaultNavs endpoint.
message QueryVaultNavsResponse {
  // navs is the list of internal NAV entries held by the vault.
  repeated VaultNAV navs = 1 [(gogoproto.nullable) = false];
  // pagination defines the pagination in the response.
  cosmos.base.query.v1beta1.PageResponse pagination = 2;
}

// QueryNavValueRequest is the request message for the Query/NavValue endpoint.
message QueryNavValueRequest {
  // id is the bech32 address of the vault or the vault's share denom to query.
  string id = 1;
  // denom is the asset denomination whose NAV entry is being queried.
  string denom = 2;
}

// QueryNavValueResponse is the response message for the Query/NavValue endpoint.
message QueryNavValueResponse {
  // nav is the internal NAV entry for the requested vault and denom.
  VaultNAV nav = 1 [(gogoproto.nullable) = false];
}

// Payment is the vault module's view of a Provenance exchange-module payment. It
// mirrors the exchange Payment, exposing only the fields relevant to the vault's
// asset settlement workflow.
message Payment {
  // source is the account that created the payment and owns the escrowed source_amount.
  string source = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
  // source_amount is the funds the source pays the target. A hold is placed on this
  // amount in the source account until the payment is accepted, rejected, or cancelled.
  repeated cosmos.base.v1beta1.Coin source_amount = 2 [
    (gogoproto.nullable) = false,
    (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
  ];
  // target is the account that can accept the payment; for these queries it is the vault.
  string target = 3 [(cosmos_proto.scalar) = "cosmos.AddressString"];
  // target_amount is the funds the target pays the source in exchange for source_amount.
  repeated cosmos.base.v1beta1.Coin target_amount = 4 [
    (gogoproto.nullable) = false,
    (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
  ];
  // external_id, together with source, uniquely identifies the payment.
  string external_id = 5;
}

// QueryVaultPaymentRequest is the request message for the Query/VaultPayment endpoint.
message QueryVaultPaymentRequest {
  // id is the bech32 address of the vault or the vault's share denom to query.
  string id = 1;
  // source is the bech32 address of the account that created the payment.
  string source = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"];
  // external_id, together with source, uniquely identifies the payment.
  string external_id = 3;
}

// QueryVaultPaymentResponse is the response message for the Query/VaultPayment endpoint.
message QueryVaultPaymentResponse {
  // payment is the pending exchange-module payment targeting the vault.
  Payment payment = 1 [(gogoproto.nullable) = false];
}

// QueryVaultPaymentsRequest is the request message for the Query/VaultPayments endpoint.
message QueryVaultPaymentsRequest {
  // id is the bech32 address of the vault or the vault's share denom to query.
  string id = 1;
  // pagination defines an optional pagination for the request.
  cosmos.base.query.v1beta1.PageRequest pagination = 2;
}

// QueryVaultPaymentsResponse is the response message for the Query/VaultPayments endpoint.
message QueryVaultPaymentsResponse {
  // payments is the list of pending exchange-module payments targeting the vault.
  repeated Payment payments = 1 [(gogoproto.nullable) = false];
  // pagination defines the pagination in the response.
  cosmos.base.query.v1beta1.PageResponse pagination = 2;
}
