syntax = "proto3";

package ark.v1;

import "meshapi/gateway/annotations.proto";
import "ark/v1/types.proto";

service AdminService {
  rpc GetScheduledSweep(GetScheduledSweepRequest) returns (GetScheduledSweepResponse) {
    option (meshapi.gateway.http) = {
      get: "/v1/admin/sweeps"
    };
  }
  rpc GetRoundDetails(GetRoundDetailsRequest) returns (GetRoundDetailsResponse) {
    option (meshapi.gateway.http) = {
      get: "/v1/admin/round/{round_id}"
    };
  }
  rpc GetRounds(GetRoundsRequest) returns (GetRoundsResponse) {
    option (meshapi.gateway.http) = {
      get: "/v1/admin/rounds"
    };
  }
  rpc CreateNote(CreateNoteRequest) returns (CreateNoteResponse) {
    option (meshapi.gateway.http) = {
      post: "/v1/admin/note"
      body: "*"
    };
  }
  rpc GetScheduledSessionConfig(GetScheduledSessionConfigRequest) returns (GetScheduledSessionConfigResponse) {
    option (meshapi.gateway.http) = {
      get: "/v1/admin/scheduledSession"
    };
  }
  rpc UpdateScheduledSessionConfig(UpdateScheduledSessionConfigRequest) returns (UpdateScheduledSessionConfigResponse) {
    option (meshapi.gateway.http) = {
      post: "/v1/admin/scheduledSession"
      body: "*"
    };
  }
  rpc ClearScheduledSessionConfig(ClearScheduledSessionConfigRequest) returns (ClearScheduledSessionConfigResponse) {
    option (meshapi.gateway.http) = {
      post: "/v1/admin/scheduledSession/clear"
      body: "*"
    };
  }
  rpc ListIntents(ListIntentsRequest) returns (ListIntentsResponse) {
    option (meshapi.gateway.http) = {
      get: "/v1/admin/intents"
    };
  }
  rpc DeleteIntents(DeleteIntentsRequest) returns (DeleteIntentsResponse) {
    option (meshapi.gateway.http) = {
      post: "/v1/admin/intents/delete"
      body: "*"
    };
  }
  rpc GetIntentFees(GetIntentFeesRequest) returns (GetIntentFeesResponse){
    option (meshapi.gateway.http) = {
      get: "/v1/admin/intentFees"
    };
  }
  rpc UpdateIntentFees(UpdateIntentFeesRequest) returns (UpdateIntentFeesResponse){
    option (meshapi.gateway.http) = {
      post: "/v1/admin/intentFees"
      body: "*"
    };
  }
  rpc ClearIntentFees(ClearIntentFeesRequest) returns (ClearIntentFeesResponse){
    option (meshapi.gateway.http) = {
      post: "/v1/admin/intentFees/clear"
      body: "*"
    };
  }
  rpc GetConvictions(GetConvictionsRequest) returns (GetConvictionsResponse) {
    option (meshapi.gateway.http) = {
      get: "/v1/admin/convictions/{ids}"
    };
  }
  rpc GetConvictionsInRange(GetConvictionsInRangeRequest) returns (GetConvictionsInRangeResponse) {
    option (meshapi.gateway.http) = {
      get: "/v1/admin/convictionsInRange"
    };
  }
  rpc GetConvictionsByRound(GetConvictionsByRoundRequest) returns (GetConvictionsByRoundResponse) {
    option (meshapi.gateway.http) = {
      get: "/v1/admin/convictionsByRound/{round_id}"
    };
  }
  rpc GetActiveScriptConvictions(GetActiveScriptConvictionsRequest) returns (GetActiveScriptConvictionsResponse) {
    option (meshapi.gateway.http) = {
      get: "/v1/admin/convictionsByScript/{script}"
    };
  }
  rpc PardonConviction(PardonConvictionRequest) returns (PardonConvictionResponse) {
    option (meshapi.gateway.http) = {
      post: "/v1/admin/convictions/{id}/pardon"
      body: "*"
    };
  }
  rpc BanScript(BanScriptRequest) returns (BanScriptResponse) {
    option (meshapi.gateway.http) = {
      post: "/v1/admin/conviction/ban"
      body: "*"
    };
  }
  rpc RevokeAuth(RevokeAuthRequest) returns (RevokeAuthResponse) {
    option (meshapi.gateway.http) = {
      post: "/v1/admin/auth/revoke"
      body: "*"
    };
  }
  rpc GetExpiringLiquidity(GetExpiringLiquidityRequest) returns (GetExpiringLiquidityResponse) {
    option (meshapi.gateway.http) = {
      get: "/v1/admin/liquidity/expiring"
    };
  }
  rpc GetRecoverableLiquidity(GetRecoverableLiquidityRequest) returns (GetRecoverableLiquidityResponse) {
    option (meshapi.gateway.http) = {
      get: "/v1/admin/liquidity/recoverable"
    };
  }
  rpc Sweep(SweepRequest) returns (SweepResponse) {
    option (meshapi.gateway.http) = {
      post: "/v1/admin/sweep"
      body: "*"
    };
  }
}

message GetScheduledSweepRequest {}
message GetScheduledSweepResponse {
  repeated ScheduledSweep sweeps = 1;
}

message GetRoundDetailsRequest {
  string round_id = 1;
}
message GetRoundDetailsResponse {
  string round_id = 1;
  int64 started_at = 2;
  int64 ended_at = 3;
  string commitment_txid = 4;
  string forfeited_amount = 5;
  string total_vtxos_amount = 6;
  string total_exit_amount = 7;
  string total_fee_amount = 8;
  repeated string inputs_vtxos = 9;
  repeated string outputs_vtxos = 10;
  repeated string exit_addresses = 11;
}

message GetRoundsRequest {
  int64 after = 1;
  int64 before = 2;
  bool with_failed = 3;
  bool with_completed = 4;
}
message GetRoundsResponse {
  repeated string rounds = 1;
}

message CreateNoteRequest {
  uint32 amount = 1;
  uint32 quantity = 2;
}
message CreateNoteResponse {
  repeated string notes = 1;
}

message GetScheduledSessionConfigRequest {}
message GetScheduledSessionConfigResponse {
  ScheduledSessionConfig config = 1;
}

message UpdateScheduledSessionConfigRequest {
  ScheduledSessionConfig config = 1;
}
message UpdateScheduledSessionConfigResponse {}

message ClearScheduledSessionConfigRequest {}
message ClearScheduledSessionConfigResponse {}

message ListIntentsRequest {
  repeated string intent_ids = 1;
}
message ListIntentsResponse {
  repeated IntentInfo intents = 1;
}

message DeleteIntentsRequest {
  repeated string intent_ids = 1;
}
message DeleteIntentsResponse {}

message GetIntentFeesRequest {}

message GetIntentFeesResponse {
  IntentFees fees = 1;
}

message UpdateIntentFeesRequest {
  IntentFees fees = 1;
}

message UpdateIntentFeesResponse {}

message ClearIntentFeesRequest {}

message ClearIntentFeesResponse {}

message GetConvictionsRequest {
  repeated string ids = 1;
}
message GetConvictionsResponse {
  repeated Conviction convictions = 1;
}

message GetConvictionsInRangeRequest {
  int64 from = 1; // Unix timestamp
  int64 to = 2; // Unix timestamp
}
message GetConvictionsInRangeResponse {
  repeated Conviction convictions = 1;
}

message GetConvictionsByRoundRequest {
  string round_id = 1;
}
message GetConvictionsByRoundResponse {
  repeated Conviction convictions = 1;
}

message GetActiveScriptConvictionsRequest {
  string script = 1;
}
message GetActiveScriptConvictionsResponse {
  repeated Conviction convictions = 1;
}

message PardonConvictionRequest {
  string id = 1;
}
message PardonConvictionResponse {}

message BanScriptRequest {
  string script = 1;
  int64 ban_duration = 2; // 0 = permanent ban
  string reason = 3;
}
message BanScriptResponse {}

message RevokeAuthRequest {
  string token = 1;
}
message RevokeAuthResponse {
  string token = 1;
}

message SweepableOutput {
  string txid = 1;
  uint32 vout = 2;
  string amount = 3;
  int64 scheduled_at = 4;
}

message ScheduledSweep {
  string round_id = 1;
  repeated SweepableOutput outputs = 2;
  bool confirmed = 3;
}

message ScheduledSessionConfig {
  int64 start_time = 1;
  int64 end_time = 2;
  int64 period = 3;
  int64 duration = 4;
  int64 round_min_participants_count = 5;
  int64 round_max_participants_count = 6;
  FeeInfo fees = 7;
}

message IntentInput {
  string txid = 1;
  uint32 vout = 2;
  uint64 amount = 3;
}

message IntentInfo {
  string id = 1;
  int64 created_at = 2;
  repeated Output receivers = 3;
  repeated IntentInput inputs = 4;
  repeated IntentInput boarding_inputs = 5;
  repeated string cosigners_public_keys = 6;
  Intent intent = 7;
}

message IntentFees {
  string offchain_input_fee = 1;
  string onchain_input_fee = 2;
  string offchain_output_fee = 3;
  string onchain_output_fee = 4;
}

message Output {
  oneof destination {
    string vtxo_script = 1;
    string onchain_address = 2;
  }; // onchain or off-chain
  uint64 amount = 3; // Amount to send in satoshis.
}

enum CrimeType {
  CRIME_TYPE_UNSPECIFIED = 0;
  CRIME_TYPE_MUSIG2_NONCE_SUBMISSION = 1;
  CRIME_TYPE_MUSIG2_SIGNATURE_SUBMISSION = 2;
  CRIME_TYPE_MUSIG2_INVALID_SIGNATURE = 3;
  CRIME_TYPE_FORFEIT_SUBMISSION = 4;
  CRIME_TYPE_FORFEIT_INVALID_SIGNATURE = 5;
  CRIME_TYPE_BOARDING_INPUT_SUBMISSION = 6;
  CRIME_TYPE_MANUAL_BAN = 7;
}

enum ConvictionType {
  CONVICTION_TYPE_UNSPECIFIED = 0;
  CONVICTION_TYPE_SCRIPT = 1;
}

message Conviction {
  string id = 1;
  ConvictionType type = 2;
  int64 created_at = 3;
  int64 expires_at = 4; // 0 if never expires
  bool pardoned = 5;
  string script = 6; // Only set for script convictions
  CrimeType crime_type = 7;
  string round_id = 8;
  string reason = 9;
}

message GetExpiringLiquidityRequest {
  int64 after = 1; // expires after this timestamp
  int64 before = 2; // expires before this timestamp
}
message GetExpiringLiquidityResponse {
  uint64 amount = 1;
}

message GetRecoverableLiquidityRequest {}
message GetRecoverableLiquidityResponse {
  uint64 amount = 1;
}

message SweepRequest {
  bool connectors = 1;
  repeated string commitment_txids = 2;
}
message SweepResponse {
  string txid = 1;
  string hex = 2;
}