Skip to main content

breez_sdk_spark/signer/
external_spark.rs

1//! External (foreign) high-level Spark signer trait.
2//!
3//! Mirrors `spark_wallet::SparkSigner` using FFI-compatible types so an
4//! integrator can implement the Spark flow-signing surface directly.
5//! The SDK wraps an implementation in
6//! [`ExternalSparkSignerAdapter`](super::ExternalSparkSignerAdapter) to obtain a
7//! native `spark_wallet::SparkSigner`.
8
9use crate::error::SignerError;
10
11use super::external_spark_types::{
12    ExternalFrostJob, ExternalFrostShareResult, ExternalPrepareClaimRequest,
13    ExternalPrepareLightningReceiveRequest, ExternalPrepareStaticDepositClaimRequest,
14    ExternalPrepareStaticDepositRequest, ExternalPrepareTokenTransactionRequest,
15    ExternalPrepareTransferRequest, ExternalPreparedClaim, ExternalPreparedLightningReceive,
16    ExternalPreparedStaticDeposit, ExternalPreparedStaticDepositClaim,
17    ExternalPreparedTokenTransaction, ExternalPreparedTransfer, ExternalSignSparkInvoiceRequest,
18    ExternalSignStaticDepositRefundRequest, ExternalSignedSparkInvoice,
19    ExternalStartStaticDepositRefundRequest, ExternalStartedStaticDepositRefund,
20};
21use super::external_types::{
22    EcdsaSignatureBytes, ExternalFrostSignature, ExternalTreeNodeId, PublicKeyBytes,
23    SchnorrSignatureBytes,
24};
25
26/// FFI-compatible mirror of `spark_wallet::SparkSigner`.
27#[cfg_attr(
28    feature = "uniffi",
29    uniffi::export(with_foreign, async_runtime = "tokio")
30)]
31#[macros::async_trait]
32pub trait ExternalSparkSigner: Send + Sync {
33    /// The wallet identity public key (33 bytes compressed).
34    async fn get_identity_public_key(&self) -> Result<PublicKeyBytes, SignerError>;
35
36    /// The public key of the leaf signing key derived from `leaf_id`.
37    async fn get_public_key_for_leaf(
38        &self,
39        leaf_id: ExternalTreeNodeId,
40    ) -> Result<PublicKeyBytes, SignerError>;
41
42    /// Whether this signer is backed by a remote service, so its operations are
43    /// network round-trips rather than local computation. Local signers return
44    /// false; a hosted signer like Turnkey returns true so the SDK can avoid
45    /// redundant calls, e.g. re-deriving keys for leaves it has already verified.
46    fn is_remote(&self) -> bool {
47        false
48    }
49
50    /// The static-deposit signing public key at `index`.
51    async fn get_static_deposit_public_key(
52        &self,
53        index: u32,
54    ) -> Result<PublicKeyBytes, SignerError>;
55
56    /// ECDSA-sign a server authentication challenge with the identity key.
57    async fn sign_authentication_challenge(
58        &self,
59        challenge: Vec<u8>,
60    ) -> Result<EcdsaSignatureBytes, SignerError>;
61
62    /// ECDSA-sign an arbitrary user message with the identity key.
63    async fn sign_message(&self, message: Vec<u8>) -> Result<EcdsaSignatureBytes, SignerError>;
64
65    /// Schnorr-sign `sighash` to spend a tree leaf's P2TR refund output as a
66    /// BIP341 key-path spend (empty script tree), with the leaf signing key
67    /// derived from `leaf_id`.
68    async fn sign_leaf_refund_spend(
69        &self,
70        leaf_id: ExternalTreeNodeId,
71        sighash: Vec<u8>,
72    ) -> Result<SchnorrSignatureBytes, SignerError>;
73
74    /// Produce FROST shares for a batch of jobs.
75    async fn sign_frost(
76        &self,
77        jobs: Vec<ExternalFrostJob>,
78    ) -> Result<Vec<ExternalFrostShareResult>, SignerError>;
79
80    /// Prepare an outbound transfer (key-tweak + packages + payload signature).
81    async fn prepare_transfer(
82        &self,
83        request: ExternalPrepareTransferRequest,
84    ) -> Result<ExternalPreparedTransfer, SignerError>;
85
86    /// Claim an inbound transfer (key-tweak step).
87    async fn prepare_claim(
88        &self,
89        request: ExternalPrepareClaimRequest,
90    ) -> Result<ExternalPreparedClaim, SignerError>;
91
92    /// Prepare a Lightning receive (in-enclave preimage + Feldman split).
93    async fn prepare_lightning_receive(
94        &self,
95        request: ExternalPrepareLightningReceiveRequest,
96    ) -> Result<ExternalPreparedLightningReceive, SignerError>;
97
98    /// Prepare a static deposit (export secret to SSP + FROST-sign tree txs).
99    async fn prepare_static_deposit(
100        &self,
101        request: ExternalPrepareStaticDepositRequest,
102    ) -> Result<ExternalPreparedStaticDeposit, SignerError>;
103
104    /// Begin a static-deposit refund (user-commits-first).
105    async fn start_static_deposit_refund(
106        &self,
107        request: ExternalStartStaticDepositRefundRequest,
108    ) -> Result<ExternalStartedStaticDepositRefund, SignerError>;
109
110    /// Finish a static-deposit refund (aggregate into the final signature).
111    async fn sign_static_deposit_refund(
112        &self,
113        request: ExternalSignStaticDepositRefundRequest,
114    ) -> Result<ExternalFrostSignature, SignerError>;
115
116    /// Schnorr-sign a Spark invoice (sats or tokens) with the identity key.
117    async fn sign_spark_invoice(
118        &self,
119        request: ExternalSignSparkInvoiceRequest,
120    ) -> Result<ExternalSignedSparkInvoice, SignerError>;
121
122    /// Schnorr-sign a token-transaction digest with the identity key.
123    async fn prepare_token_transaction(
124        &self,
125        request: ExternalPrepareTokenTransactionRequest,
126    ) -> Result<ExternalPreparedTokenTransaction, SignerError>;
127
128    /// Prepare a static-deposit claim (export secret in the clear + sign).
129    async fn prepare_static_deposit_claim(
130        &self,
131        request: ExternalPrepareStaticDepositClaimRequest,
132    ) -> Result<ExternalPreparedStaticDepositClaim, SignerError>;
133}