newton-core 0.4.19

newton protocol core sdk
//! Shared request/response types for the operator DKG and PSS-refresh RPCs.
//!
//! These types are used by both the operator (RPC server) and the gateway (RPC
//! client / ceremony coordinator). Defining them once here — rather than
//! duplicating them in each crate — is what lets the two sides authenticate
//! requests with the canonical [`Authenticated`] envelope
//! (`newton_chainio::operator_rpc_auth`): the envelope's `paramsHash` is
//! `keccak256(bincode::serialize(&inner))`, so the request struct must produce
//! byte-identical bincode on both sides. A single shared definition guarantees
//! that without any canonicalization rules.
//!
//! [`Authenticated`]: https://docs.rs/newton-chainio
//!
//! # Auth model
//!
//! Every request carries a `chain_id` field. The operator uses it to select the
//! per-chain context (and its task-manager address for EIP-712 domain
//! separation) and rejects the request if it does not match the chain the
//! endpoint is bound to. The gateway signs an [`Authenticated`] envelope whose
//! `paramsHash` covers the entire request body, so no field can be tampered
//! with in transit. There is no longer a per-request `gateway_signature` string
//! embedded in the body — the envelope replaces it.

use std::collections::BTreeMap;

use serde::{Deserialize, Serialize};

/// Request for `newt_dkgRound1`: initialise a FROST DKG ceremony for one operator.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DkgRound1Request {
    /// Chain ID this ceremony targets. Bound by the auth envelope.
    pub chain_id: u64,
    /// Unique ceremony identifier.
    pub ceremony_id: String,
    /// 1-based operator index used to derive the FROST Identifier.
    pub participant_index: u32,
    /// Minimum number of signers required for threshold operations.
    pub threshold: u16,
    /// Total number of DKG participants.
    pub total_participants: u16,
}

/// Response from an operator after completing FROST DKG Round 1.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DkgRound1Response {
    /// Hex-encoded JSON-serialized FROST Round1Package (broadcast to all participants).
    pub round1_package: String,
}

/// Request for `newt_dkgRound2`, containing all other participants' Round 1 packages.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DkgRound2Request {
    /// Chain ID this ceremony targets. Bound by the auth envelope.
    pub chain_id: u64,
    /// Unique ceremony identifier.
    pub ceremony_id: String,
    /// Participant index (u32 as string) → hex-encoded JSON Round1Package from each other participant.
    pub round1_packages: BTreeMap<String, String>,
}

/// Response from an operator after completing FROST DKG Round 2.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DkgRound2Response {
    /// Recipient participant index (u32 as string) → hex-encoded JSON Round2Package.
    pub round2_packages: BTreeMap<String, String>,
}

/// Request for `newt_dkgRound3`, containing all Round 1 and directed Round 2 packages.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DkgRound3Request {
    /// Chain ID this ceremony targets. Bound by the auth envelope.
    pub chain_id: u64,
    /// Unique ceremony identifier.
    pub ceremony_id: String,
    /// All Round 1 packages excluding self: participant index → hex-encoded JSON.
    pub round1_packages: BTreeMap<String, String>,
    /// Round 2 packages addressed to this operator: sender index → hex-encoded JSON.
    pub round2_packages: BTreeMap<String, String>,
}

/// Response from an operator after completing FROST DKG Round 3.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DkgRound3Response {
    /// Hex-encoded compressed EdwardsPoint representing this operator's verifying share
    /// (per-participant public key `pk_i = s_i * G`). NOT the group verifying key.
    pub verifying_share_hex: String,
    /// This operator's 1-based share index.
    pub share_index: u32,
}

/// Request to cancel an in-progress DKG ceremony on the operator side.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DkgCancelRequest {
    /// Chain ID this ceremony targets. Bound by the auth envelope.
    pub chain_id: u64,
    /// Ceremony identifier to cancel.
    pub ceremony_id: String,
}

/// Response confirming whether the operator's ceremony state was cleared.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DkgCancelResponse {
    /// Whether the operator's DKG state was actually cleared.
    pub cleared: bool,
}

/// Request for `newt_dkgRefreshRound`: generate a refresh/reshare polynomial
/// and return commitments + per-recipient shares.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RefreshRoundRequest {
    /// Chain ID this refresh targets. Bound by the auth envelope.
    pub chain_id: u64,
    /// Unique identifier for this refresh ceremony.
    pub ceremony_id: String,
    /// Target epoch for this refresh.
    pub epoch_id: u64,
    /// Signature threshold (minimum co-signers).
    pub threshold: u16,
    /// Total number of participants in the ceremony.
    pub total_participants: u16,
    /// Participant index (as string) to socket URL.
    pub participants: BTreeMap<String, String>,
    /// Operation mode: "refresh" (same group) or "reshare" (new group).
    pub mode: String,
}

/// A single operator's refresh contribution (Feldman VSS commitments +
/// per-recipient encrypted shares).
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RefreshContribution {
    /// 1-based participant index of the contributing operator.
    pub operator_index: u32,
    /// Feldman VSS commitments, hex-encoded compressed EdwardsPoint values.
    pub commitments_hex: Vec<String>,
    /// Per-recipient sub-shares keyed by recipient participant index (as string)
    /// to hex-encoded Scalar bytes.
    pub encrypted_shares: BTreeMap<String, String>,
}

/// Request for `newt_dkgRefreshApply`: verify received contributions and apply
/// the refresh delta (or reshare interpolation) to the current key share.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RefreshApplyRequest {
    /// Chain ID this refresh targets. Bound by the auth envelope.
    pub chain_id: u64,
    /// Unique identifier for this refresh ceremony.
    pub ceremony_id: String,
    /// Target epoch for this refresh.
    pub epoch_id: u64,
    /// All collected contributions from the collect phase.
    pub contributions: Vec<RefreshContribution>,
    /// Operation mode: "refresh" (same group) or "reshare" (new group).
    pub mode: String,
}

/// Response from an operator after applying refresh contributions.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RefreshApplyResponse {
    /// 1-based participant index of this operator.
    pub operator_index: u32,
    /// Whether the operator successfully applied the refresh.
    pub success: bool,
    /// Hex-encoded new public share after refresh (present on success).
    pub new_public_share_hex: Option<String>,
}