use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct VerificationMethod {
pub id: String,
#[serde(rename = "type")]
pub type_: VerificationMethodType,
pub controller: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub public_key_multibase: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub public_key_jwk: Option<serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub public_key_pem: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub blockchain_account_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub ethereum_address: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
pub enum VerificationMethodType {
#[default]
#[serde(rename = "Ed25519VerificationKey2020")]
Ed25519VerificationKey2020,
#[serde(rename = "Ed25519VerificationKey2018")]
Ed25519VerificationKey2018,
#[serde(rename = "X25519KeyAgreementKey2020")]
X25519KeyAgreementKey2020,
#[serde(rename = "X25519KeyAgreementKey2019")]
X25519KeyAgreementKey2019,
#[serde(rename = "EcdsaSecp256k1VerificationKey2019")]
EcdsaSecp256k1VerificationKey2019,
#[serde(rename = "EcdsaSecp256k1RecoveryMethod2020")]
EcdsaSecp256k1RecoveryMethod2020,
#[serde(rename = "JsonWebKey2020")]
JsonWebKey2020,
#[serde(rename = "Bls12381G2Key2020")]
Bls12381G2Key2020,
#[serde(rename = "GpgVerificationKey2020")]
GpgVerificationKey2020,
#[serde(rename = "RsaVerificationKey2018")]
RsaVerificationKey2018,
#[serde(untagged)]
Custom(String),
}
impl fmt::Display for VerificationMethodType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Ed25519VerificationKey2020 => write!(f, "Ed25519VerificationKey2020"),
Self::Ed25519VerificationKey2018 => write!(f, "Ed25519VerificationKey2018"),
Self::X25519KeyAgreementKey2020 => write!(f, "X25519KeyAgreementKey2020"),
Self::X25519KeyAgreementKey2019 => write!(f, "X25519KeyAgreementKey2019"),
Self::EcdsaSecp256k1VerificationKey2019 => write!(f, "EcdsaSecp256k1VerificationKey2019"),
Self::EcdsaSecp256k1RecoveryMethod2020 => write!(f, "EcdsaSecp256k1RecoveryMethod2020"),
Self::JsonWebKey2020 => write!(f, "JsonWebKey2020"),
Self::Bls12381G2Key2020 => write!(f, "Bls12381G2Key2020"),
Self::GpgVerificationKey2020 => write!(f, "GpgVerificationKey2020"),
Self::RsaVerificationKey2018 => write!(f, "RsaVerificationKey2018"),
Self::Custom(s) => write!(f, "{s}"),
}
}
}
impl VerificationMethod {
pub fn new_ed25519(
id: String,
controller: String,
public_key: &[u8; 32],
) -> Self {
use multibase::Base;
let public_key_multibase = multibase::encode(Base::Base58Btc, public_key);
Self {
id,
type_: VerificationMethodType::Ed25519VerificationKey2020,
controller,
public_key_multibase: Some(public_key_multibase),
..Default::default()
}
}
pub fn new_x25519(
id: String,
controller: String,
public_key: &[u8; 32],
) -> Self {
use multibase::Base;
let public_key_multibase = multibase::encode(Base::Base58Btc, public_key);
Self {
id,
type_: VerificationMethodType::X25519KeyAgreementKey2020,
controller,
public_key_multibase: Some(public_key_multibase),
..Default::default()
}
}
pub fn new_ethereum(
id: String,
controller: String,
ethereum_address: String,
) -> Self {
Self {
id,
type_: VerificationMethodType::EcdsaSecp256k1RecoveryMethod2020,
controller,
ethereum_address: Some(ethereum_address),
..Default::default()
}
}
pub fn is_signing_method(&self) -> bool {
matches!(self.type_,
VerificationMethodType::Ed25519VerificationKey2020 |
VerificationMethodType::Ed25519VerificationKey2018 |
VerificationMethodType::EcdsaSecp256k1VerificationKey2019 |
VerificationMethodType::EcdsaSecp256k1RecoveryMethod2020 |
VerificationMethodType::Bls12381G2Key2020 |
VerificationMethodType::RsaVerificationKey2018
)
}
pub fn is_key_agreement_method(&self) -> bool {
matches!(self.type_,
VerificationMethodType::X25519KeyAgreementKey2020 |
VerificationMethodType::X25519KeyAgreementKey2019
)
}
}