Skip to main content

df_papertrade_core/client/
error.rs

1//! The client's error type. It separates refusals made before sending, steps to take first,
2//! answers from the relayer or Hyperliquid, and failures of the store, wallet or transport.
3
4use crate::client::relayer::{Accepted, RelayerError};
5use crate::trade::Refusal;
6use crate::trade::math::OpenRefusal;
7use crate::utils::BadWire;
8
9use crate::account::session::KeyState;
10use crate::account::store::StoreError;
11use crate::account::wallet::WalletError;
12
13/// Why a client call failed.
14#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
15pub enum Error {
16    /// The intent is malformed (leverage out of range, no margin, no positions to close).
17    /// Nothing was sent.
18    #[error("{0}")]
19    Invalid(String),
20    /// The protocol would refuse the open. Nothing was sent.
21    #[error(transparent)]
22    Open(OpenRefusal),
23    /// More than the account holds. Nothing was sent.
24    #[error("{0}")]
25    InsufficientFunds(String),
26    /// The account has not streamed yet, so nothing can be checked.
27    #[error("the account has not streamed yet")]
28    NoAccount,
29    /// The session key cannot sign yet. [`KeyState::Missing`] needs a key made,
30    /// [`KeyState::Unregistered`] needs the wallet to register it.
31    #[error("{}", match .0 {
32        KeyState::Missing => "enable trading first: no session key",
33        KeyState::Unregistered => "register the session key first",
34        KeyState::Ready => "the session key is ready",
35    })]
36    NeedsKey(KeyState),
37    /// The signing wallet is not the account's owner.
38    #[error("the wallet is {wallet}, not the account's owner {owner}")]
39    WrongWallet { wallet: String, owner: String },
40    #[error(transparent)]
41    Wallet(WalletError),
42    /// A signature that does not recover to the account's owner, or a session key that cannot
43    /// sign.
44    #[error("{0}")]
45    Signature(String),
46    #[error(transparent)]
47    Relayer(#[from] RelayerError),
48    /// The relayer answered but did not keep the intent.
49    #[error("the relayer answered {}", .0.state)]
50    NotKept(Accepted),
51    /// Hyperliquid refused a deposit send, with its message. Later sends were not made.
52    #[error("Hyperliquid refused the send: {0}")]
53    Exchange(String),
54    #[error(transparent)]
55    Transport(#[from] df_hyperliquid_core::client::TransportError),
56    #[error(transparent)]
57    Chain(crate::client::chain::ReadError),
58    #[error(transparent)]
59    Precompile(df_hyperliquid_core::client::evm::ReadError),
60    #[error(transparent)]
61    Store(#[from] StoreError),
62    #[error("no randomness: {0}")]
63    Random(String),
64    /// An answer that could not be decoded.
65    #[error("{0}")]
66    Decode(String),
67}
68
69impl From<BadWire> for Error {
70    fn from(e: BadWire) -> Self {
71        Error::Decode(e.to_string())
72    }
73}
74
75impl From<Refusal> for Error {
76    fn from(e: Refusal) -> Self {
77        Error::Invalid(e.to_string())
78    }
79}
80
81impl From<OpenRefusal> for Error {
82    fn from(e: OpenRefusal) -> Self {
83        Error::Open(e)
84    }
85}
86
87impl From<WalletError> for Error {
88    fn from(e: WalletError) -> Self {
89        Error::Wallet(e)
90    }
91}