penumbra_sdk_auction/auction/
nft.rs1use crate::auction::id::AuctionId;
2use anyhow::{anyhow, Result};
3use penumbra_sdk_asset::asset::{self, Metadata};
4use penumbra_sdk_proto::{core::component::auction::v1 as pb, DomainType};
5use regex::Regex;
6
7#[derive(Debug, Clone)]
9pub struct AuctionNft {
10 pub id: AuctionId,
12 pub seq: u64,
15 pub metadata: asset::Metadata,
17}
18
19impl AuctionNft {
20 pub fn new(id: AuctionId, seq: u64) -> AuctionNft {
21 let metadata = asset::REGISTRY
22 .parse_denom(&format!("auctionnft_{seq}_{id}"))
23 .expect("auction nft denom is valid");
24 AuctionNft { id, seq, metadata }
25 }
26
27 pub fn asset_id(&self) -> asset::Id {
28 self.metadata.id()
29 }
30}
31
32impl DomainType for AuctionNft {
34 type Proto = pb::AuctionNft;
35}
36
37impl From<AuctionNft> for pb::AuctionNft {
38 fn from(domain: AuctionNft) -> Self {
39 Self {
40 id: Some(domain.id.into()),
41 seq: domain.seq,
42 }
43 }
44}
45
46impl TryFrom<pb::AuctionNft> for AuctionNft {
47 type Error = anyhow::Error;
48
49 fn try_from(msg: pb::AuctionNft) -> Result<Self, Self::Error> {
50 let id: AuctionId = msg
51 .id
52 .ok_or_else(|| anyhow!("AuctionNft message is missing an auction id"))?
53 .try_into()?;
54 let seq = msg.seq;
55 Ok(AuctionNft::new(id, seq))
56 }
57}
58
59impl TryFrom<Metadata> for AuctionNft {
60 type Error = anyhow::Error;
61
62 fn try_from(denom: Metadata) -> Result<Self, Self::Error> {
63 let regex = Regex::new(
64 "^auctionnft_(?P<seq_num>[0-9]+)_(?P<auction_id>pauctid1[a-zA-HJ-NP-Z0-9]+)$",
65 )
66 .expect("regex is valid");
67
68 let denom_string = denom.to_string();
69
70 let captures = regex
71 .captures(&denom_string)
72 .ok_or_else(|| anyhow!("denom {} is not a valid auction nft", denom))?;
73
74 let seq_num = captures
75 .name("seq_num")
76 .ok_or_else(|| anyhow!("sequence number not found"))?
77 .as_str();
78 let auction_id = captures
79 .name("auction_id")
80 .ok_or_else(|| anyhow!("auction ID not found"))?
81 .as_str();
82
83 let seq_num: u64 = seq_num
84 .parse()
85 .map_err(|_| anyhow!("Failed to parse seq_num to u64"))?;
86
87 let auction_id: AuctionId = auction_id
88 .parse()
89 .map_err(|_| anyhow!("Failed to parse auction_id to AuctionId"))?;
90
91 Ok(AuctionNft::new(auction_id, seq_num))
92 }
93}