1use serde::{Deserialize, Serialize};
2use sui_sdk_types::bcs::{FromBcs, ToBcs};
3use sui_sdk_types::{Address, MultisigMemberPublicKey, SimpleSignature, UserSignature};
4
5#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
6pub struct PublicKey(MultisigMemberPublicKey);
7
8impl From<MultisigMemberPublicKey> for PublicKey {
9 fn from(pk: MultisigMemberPublicKey) -> Self {
10 Self(pk)
11 }
12}
13
14impl TryFrom<&UserSignature> for PublicKey {
15 type Error = anyhow::Error;
16 fn try_from(signature: &UserSignature) -> Result<Self, anyhow::Error> {
17 Ok(match signature {
18 UserSignature::Simple(SimpleSignature::Ed25519 { public_key, .. }) => {
19 Self(MultisigMemberPublicKey::Ed25519(*public_key))
20 }
21 UserSignature::Simple(SimpleSignature::Secp256k1 { public_key, .. }) => {
22 Self(MultisigMemberPublicKey::Secp256k1(*public_key))
23 }
24 UserSignature::Simple(SimpleSignature::Secp256r1 { public_key, .. }) => {
25 Self(MultisigMemberPublicKey::Secp256r1(*public_key))
26 }
27 UserSignature::ZkLogin(zk_login_authenticator) => {
28 Self(MultisigMemberPublicKey::ZkLogin(
29 zk_login_authenticator.inputs.public_identifier().clone(),
30 ))
31 }
32 UserSignature::Passkey(passkey_authenticator) => Self(
33 MultisigMemberPublicKey::Passkey(passkey_authenticator.public_key()),
34 ),
35 s => anyhow::bail!(
36 "unable to extract public key from signature with scheme {}",
37 s.scheme().name(),
38 ),
39 })
40 }
41}
42
43impl PublicKey {
44 pub fn from_base64(base64: &str) -> Result<Self, anyhow::Error> {
45 let pk = MultisigMemberPublicKey::from_bcs_base64(base64)?;
46 Ok(Self(pk))
47 }
48 pub fn to_base64(&self) -> String {
49 self.0
50 .to_bcs_base64()
51 .expect("serializing PublicKey to BCS should not fail")
52 }
53 pub fn address(&self) -> Result<Address, anyhow::Error> {
54 Ok(match self.0 {
55 MultisigMemberPublicKey::Ed25519(public_key) => public_key.derive_address(),
56 MultisigMemberPublicKey::Secp256k1(public_key) => public_key.derive_address(),
57 MultisigMemberPublicKey::Secp256r1(public_key) => public_key.derive_address(),
58 MultisigMemberPublicKey::Passkey(public_key) => public_key.derive_address(),
59 _ => anyhow::bail!("unable to extract single address from public key {self:?}"),
60 })
61 }
62}