Use Currency enum to refer to CAIP-2 namespaces instead of chain IDs
This commit is contained in:
parent
8df8fd3c8c
commit
690a03946e
4 changed files with 29 additions and 28 deletions
|
@ -19,13 +19,16 @@ pub const ETHEREUM_EIP191_PROOF: &str = "ethereum-eip191-00";
|
|||
// https://github.com/w3c-ccg/did-pkh/blob/main/did-pkh-method-draft.md
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct DidPkh {
|
||||
chain_id: ChainId,
|
||||
pub chain_id: ChainId,
|
||||
pub address: String,
|
||||
}
|
||||
|
||||
impl DidPkh {
|
||||
pub fn from_address(currency: &Currency, address: &str) -> Self {
|
||||
let chain_id = currency.chain_id();
|
||||
let chain_id = match currency {
|
||||
Currency::Ethereum => ChainId::ethereum_mainnet(),
|
||||
Currency::Monero => unimplemented!(),
|
||||
};
|
||||
let address = currency.normalize_address(address);
|
||||
Self { chain_id, address }
|
||||
}
|
||||
|
|
|
@ -58,6 +58,7 @@ use crate::models::users::queries::{
|
|||
get_user_by_did,
|
||||
};
|
||||
use crate::models::users::types::UserCreateData;
|
||||
use crate::utils::caip2::ChainId;
|
||||
use crate::utils::crypto::{
|
||||
hash_password,
|
||||
generate_private_key,
|
||||
|
@ -238,7 +239,7 @@ async fn create_identity_proof(
|
|||
let actor_id = current_user.profile.actor_id(&config.instance_url());
|
||||
let did = proof_data.did.parse::<DidPkh>()
|
||||
.map_err(|_| ValidationError("invalid DID"))?;
|
||||
if did.currency() != Some(Currency::Ethereum) {
|
||||
if did.chain_id != ChainId::ethereum_mainnet() {
|
||||
// DID must point to Ethereum Mainnet because it is a valid
|
||||
// identifier on any Ethereum chain
|
||||
return Err(ValidationError("unsupported chain ID").into());
|
||||
|
|
|
@ -5,6 +5,8 @@ use regex::Regex;
|
|||
use serde::{Deserialize, Deserializer, de::Error as DeserializerError};
|
||||
|
||||
const CAIP2_RE: &str = r"(?P<namespace>[-a-z0-9]{3,8}):(?P<reference>[-a-zA-Z0-9]{1,32})";
|
||||
const CAIP2_ETHEREUM_NAMESPACE: &str = "eip155";
|
||||
const ETHEREUM_MAINNET_ID: i32 = 1;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct ChainId {
|
||||
|
@ -12,6 +14,15 @@ pub struct ChainId {
|
|||
pub reference: String,
|
||||
}
|
||||
|
||||
impl ChainId {
|
||||
pub fn ethereum_mainnet() -> Self {
|
||||
Self {
|
||||
namespace: CAIP2_ETHEREUM_NAMESPACE.to_string(),
|
||||
reference: ETHEREUM_MAINNET_ID.to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
#[error("Chain ID parse error")]
|
||||
pub struct ChainIdError;
|
||||
|
|
|
@ -23,11 +23,6 @@ impl Currency {
|
|||
format!("${}", self.code())
|
||||
}
|
||||
|
||||
/// Returns CAIP-2 chain ID
|
||||
pub fn chain_id(&self) -> ChainId {
|
||||
self.into()
|
||||
}
|
||||
|
||||
pub fn normalize_address(&self, address: &str) -> String {
|
||||
match self {
|
||||
Self::Ethereum => address.to_lowercase(),
|
||||
|
@ -36,28 +31,13 @@ impl Currency {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<&Currency> for ChainId {
|
||||
fn from(value: &Currency) -> Self {
|
||||
let (namespace, reference) = match value {
|
||||
Currency::Ethereum => ("eip155", "1"),
|
||||
Currency::Monero => unimplemented!(),
|
||||
};
|
||||
Self {
|
||||
namespace: namespace.to_string(),
|
||||
reference: reference.to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&ChainId> for Currency {
|
||||
type Error = ConversionError;
|
||||
|
||||
fn try_from(value: &ChainId) -> Result<Self, Self::Error> {
|
||||
let currency = match value.namespace.as_str() {
|
||||
"eip155" => match value.reference.as_str() {
|
||||
"1" => Self::Ethereum,
|
||||
_ => return Err(ConversionError),
|
||||
},
|
||||
"eip155" => Self::Ethereum,
|
||||
"monero" => Self::Monero, // not standard
|
||||
_ => return Err(ConversionError),
|
||||
};
|
||||
Ok(currency)
|
||||
|
@ -87,10 +67,16 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_chain_id_conversion() {
|
||||
let ethereum = Currency::Ethereum;
|
||||
let ethereum_chain_id = ChainId::from(ðereum);
|
||||
let ethereum_chain_id = ChainId::ethereum_mainnet();
|
||||
let currency = Currency::try_from(ðereum_chain_id).unwrap();
|
||||
assert_eq!(currency, ethereum);
|
||||
assert_eq!(currency, Currency::Ethereum);
|
||||
|
||||
let monero_chain_id = ChainId {
|
||||
namespace: "monero".to_string(),
|
||||
reference: "mainnet".to_string(),
|
||||
};
|
||||
let currency = Currency::try_from(&monero_chain_id).unwrap();
|
||||
assert_eq!(currency, Currency::Monero);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
Loading…
Reference in a new issue