1use crate::ApiClientWrapper;
2use xmtp_id::scw_verifier::SmartContractSignatureVerifier;
3use xmtp_id::scw_verifier::VerifierError;
4use xmtp_id::{BlockNumber, Bytes, associations::AccountId, scw_verifier::ValidationResponse};
5use xmtp_proto::backend_v1::VerifySmartContractWalletSignaturesRequest;
6use xmtp_proto::backend_v1::VerifySmartContractWalletSignaturesResponse;
7use xmtp_proto::backend_v1::verify_smart_contract_wallet_signatures_request::Signature as VerifySmartContractWalletSignatureRequestSignature;
8use xmtp_proto::prelude::XmtpBackendClient;
9
10#[xmtp_common::async_trait]
11impl<C> SmartContractSignatureVerifier for ApiClientWrapper<C>
12where
13 C: XmtpBackendClient,
14{
15 async fn is_valid_signature(
23 &self,
24 account_id: AccountId,
25 hash: [u8; 32],
26 signature: Bytes,
27 block_number: Option<BlockNumber>,
28 ) -> Result<ValidationResponse, VerifierError> {
29 let result = self
30 .verify_smart_contract_wallet_signatures(VerifySmartContractWalletSignaturesRequest {
31 signatures: vec![VerifySmartContractWalletSignatureRequestSignature {
32 account_id: account_id.into(),
33 block_number,
34 signature: signature.to_vec(),
35 hash: hash.to_vec(),
36 }],
37 })
38 .await
39 .map_err(|e| VerifierError::Other(Box::new(e) as Box<_>))?;
40
41 let VerifySmartContractWalletSignaturesResponse { responses } = result;
42
43 let response =
44 responses
45 .into_iter()
46 .next()
47 .ok_or(VerifierError::Io(std::io::Error::new(
48 std::io::ErrorKind::InvalidData,
49 "API returned empty response for signature verification request",
50 )))?;
51 Ok(ValidationResponse {
52 is_valid: response.is_valid,
53 block_number: response.block_number,
54 error: response.error,
55 })
56 }
57}