trident-sdk 0.2.0

End-user SDK for Trident deposits and cross-chain spends
Documentation
use alloy_primitives::U256;
use async_trait::async_trait;

use crate::conversions::ProtoConversionError;
use crate::deposit::DepositContext;
use crate::evm::EvmChainError;
use crate::proto::v1;
use crate::spend_attestation::SpendAttestationChainContext;

/// Errors raised by a live [`ChainHandler`] while servicing an SDK
/// operation (signing, deposit preparation, etc.). Surfaced through
/// [`crate::TridentClientError::ChainHandler`].
#[derive(Debug, thiserror::Error)]
pub enum ChainHandlerError {
    /// The wrapped handler is an EVM chain and the underlying operation
    /// failed.
    #[error(transparent)]
    EvmChain(#[from] EvmChainError),
}

/// Errors produced while materializing a [`ChainHandler`] from a pending
/// registration once the delivery service has returned deployment data.
#[derive(Debug, thiserror::Error)]
pub enum ChainHandlerBuildError {
    /// Decoding a proto-sourced contract address failed.
    #[error("Invalid proto conversion: {0}")]
    ProtoConversion(#[from] ProtoConversionError),
}

#[async_trait]
pub(crate) trait ChainHandler: Send + Sync {
    fn delivery_contract(&self) -> v1::MultiChainAddress;
    fn deposit_contract(&self) -> v1::MultiChainAddress;
    fn signer(&self) -> v1::MultiChainAddress;

    async fn sign_spend_intent(
        &self,
        intent: v1::SpendIntent,
    ) -> Result<Vec<u8>, ChainHandlerError>;

    fn prepare_deposit(
        &self,
        token: v1::MultiChainAddress,
        amount: U256,
    ) -> Result<DepositContext, ChainHandlerError>;

    fn prepare_spend_attestation(&self) -> SpendAttestationChainContext;
}

/// Materializes a [`ChainHandler`] for a specific chain family once the
/// delivery-service deployment data is in hand.
///
/// Chain-agnostic [`crate::TridentClientBuilder`] stores these as
/// `Box<dyn ChainHandlerBuilder>` and invokes [`build`](Self::build) at
/// `connect()` time.
#[async_trait]
pub(crate) trait ChainHandlerBuilder: Send + Sync {
    async fn build(
        self: Box<Self>,
        delivery_contract: v1::MultiChainAddress,
        deposit_contract: v1::MultiChainAddress,
    ) -> Result<Box<dyn ChainHandler>, ChainHandlerBuildError>;
}