use anyhow::Result;
use serde::Serialize;
#[derive(Debug, Clone, Serialize)]
pub struct KeyGenerationResult {
pub public_key: String,
pub address: String,
pub scheme: String,
pub secret: Option<String>,
pub name: Option<String>,
}
#[derive(Debug, Clone, Serialize)]
pub struct KeyImportResult {
pub public_key: String,
pub address: String,
pub scheme: String,
pub secret: Option<String>,
pub name: Option<String>,
}
#[derive(Debug, Clone, Serialize)]
pub struct SignResult {
pub signature: String,
}
#[derive(Debug, Clone, Serialize)]
pub struct VerifyResult {
pub valid: bool,
}
#[derive(Debug, Clone, Serialize)]
pub struct AddressResult {
pub address: String,
}
#[derive(Debug, Clone, Serialize)]
pub struct RecoverResult {
pub public_key: String,
pub address: String,
}
#[derive(Debug, Clone, Serialize)]
pub struct PeerIdResult {
pub peer_id: String,
}
#[derive(Debug, Clone, Serialize)]
pub struct ListKeysResult {
pub keys: Vec<KeyInfo>,
}
#[derive(Debug, Clone, Serialize)]
pub struct ClearResult {
pub removed: usize,
}
#[derive(Debug, Clone, Serialize)]
pub struct KeyInfo {
pub public_key: String,
pub address: String,
pub scheme: String,
pub secret: Option<String>,
pub name: Option<String>,
}
#[derive(Debug, Clone, Serialize)]
pub struct MessageResult {
pub message: String,
}
#[derive(Debug, Clone, Copy, Serialize, PartialEq, Eq)]
pub enum Scheme {
Secp256k1,
Ed25519,
Sr25519,
}
#[derive(Debug, Clone, Serialize)]
pub struct CommandResult {
pub scheme: Scheme,
pub result: SchemeResult,
}
#[derive(Debug, Clone, Serialize)]
pub enum SchemeResult {
Clear(ClearResult),
Generate(KeyGenerationResult),
Import(KeyImportResult),
Sign(SignResult),
Verify(VerifyResult),
Recover(RecoverResult),
Address(AddressResult),
PeerId(PeerIdResult),
List(ListKeysResult),
Message(MessageResult),
}
pub enum SchemeCommand<KeyringCommand> {
#[cfg(feature = "keyring")]
Keyring { command: KeyringCommand },
Verify {
public_key: String,
data: String,
prefix: Option<String>,
signature: String,
context: Option<String>,
},
Address {
public_key: String,
network: Option<String>,
},
Recover {
data: String,
prefix: Option<String>,
signature: String,
},
#[cfg(feature = "peer-id")]
PeerId { public_key: String },
}
pub type SchemeVerifyFn =
fn(String, String, Option<String>, String, Option<String>) -> Result<SchemeResult>;
pub type SchemeAddressFn = fn(String, Option<String>) -> Result<SchemeResult>;
pub type SchemeRecoverFn = fn(String, Option<String>, String) -> Result<SchemeResult>;
#[cfg(feature = "peer-id")]
pub type SchemePeerIdFn = fn(String) -> Result<SchemeResult>;
pub struct SchemeDescriptor<KeyringCommand> {
#[cfg(feature = "keyring")]
pub handle_keyring: fn(KeyringCommand) -> Result<SchemeResult>,
pub verify: SchemeVerifyFn,
pub address: SchemeAddressFn,
pub recover: Option<SchemeRecoverFn>,
#[cfg(feature = "peer-id")]
pub peer_id: Option<SchemePeerIdFn>,
}
pub fn execute_scheme_command<KeyringCommand>(
descriptor: &SchemeDescriptor<KeyringCommand>,
command: SchemeCommand<KeyringCommand>,
) -> Result<SchemeResult> {
match command {
#[cfg(feature = "keyring")]
SchemeCommand::Keyring { command } => (descriptor.handle_keyring)(command),
SchemeCommand::Verify {
public_key,
data,
prefix,
signature,
context,
} => (descriptor.verify)(public_key, data, prefix, signature, context),
SchemeCommand::Address {
public_key,
network,
} => (descriptor.address)(public_key, network),
SchemeCommand::Recover {
data,
prefix,
signature,
} => {
let recover_fn = descriptor
.recover
.ok_or_else(|| anyhow::anyhow!("Recovery is not supported for this scheme"))?;
recover_fn(data, prefix, signature)
}
#[cfg(feature = "peer-id")]
SchemeCommand::PeerId { public_key } => {
let peer_id_fn = descriptor.peer_id.ok_or_else(|| {
anyhow::anyhow!("PeerId derivation is not supported for this scheme")
})?;
peer_id_fn(public_key)
}
}
}