hypercall_signer/traits.rs
1use async_trait::async_trait;
2use hypercall_types::WalletAddress;
3
4use crate::{RsmSignerError, RsmSignerStatus, SignedDirective};
5
6/// Provider-agnostic RSM directive signer.
7///
8/// Implementations must produce signatures recoverable to `signer_address()` and
9/// preserve nonce/idempotency guarantees for repeated directive requests.
10#[async_trait]
11pub trait RsmSigner: Send + Sync {
12 /// Returns the on-chain signer address used for directive signatures.
13 fn signer_address(&self) -> WalletAddress;
14
15 /// Claims or reuses the next signer nonce and signs `action`.
16 ///
17 /// Repeated calls with the same `request_id`, `account`, and `action` must
18 /// return the same completed directive instead of allocating another nonce.
19 async fn sign(
20 &self,
21 request_id: &str,
22 account: &WalletAddress,
23 action: &[u8],
24 ) -> Result<SignedDirective, RsmSignerError>;
25
26 /// Signs `action` using a caller-reserved nonce.
27 ///
28 /// The caller owns nonce allocation; implementations should reject already
29 /// used nonces rather than silently moving to a different nonce.
30 async fn sign_preallocated(
31 &self,
32 request_id: &str,
33 account: &WalletAddress,
34 action: &[u8],
35 nonce: u64,
36 ) -> Result<SignedDirective, RsmSignerError>;
37
38 /// Reports signer health and nonce state.
39 async fn status(&self) -> Result<RsmSignerStatus, RsmSignerError>;
40
41 /// Returns whether `nonce` is already consumed on-chain for this signer.
42 async fn is_nonce_used(&self, nonce: u64) -> Result<bool, RsmSignerError>;
43}