1use cosmwasm_schema::{cw_serde, QueryResponses};
2use cosmwasm_std::{to_vec, Addr};
3
4pub const MAX_TEXT_LENGTH: u32 = 512;
5
6pub type TokenId = String;
7
8#[cw_serde]
9pub struct NFT {
10 pub collection: Addr,
11 pub token_id: TokenId,
12}
13
14impl NFT {
15 pub fn into_json_string(self: &NFT) -> String {
16 String::from_utf8(to_vec(&self).unwrap_or_default()).unwrap_or_default()
17 }
18}
19
20#[cw_serde]
21pub struct TextRecord {
22 pub name: String, pub value: String, pub verified: Option<bool>, }
26
27impl TextRecord {
28 pub fn new(name: impl Into<String>, value: impl Into<String>) -> Self {
29 Self {
30 name: name.into(),
31 value: value.into(),
32 verified: None,
33 }
34 }
35
36 pub fn into_json_string(self: &TextRecord) -> String {
37 String::from_utf8(to_vec(&self).unwrap_or_default()).unwrap_or_default()
38 }
39}
40
41#[cw_serde]
43#[derive(Default)]
44pub struct Metadata {
45 pub image_nft: Option<NFT>,
46 pub records: Vec<TextRecord>,
47}
48
49impl Metadata {
50 pub fn into_json_string(self: &Metadata) -> String {
56 String::from_utf8(to_vec(&self).unwrap_or_default()).unwrap_or_default()
57 }
58}
59
60#[cw_serde]
61pub enum SgNameExecuteMsg {
62 SetNameMarketplace { address: String },
64 AssociateAddress {
67 name: String,
68 address: Option<String>,
69 },
70 UpdateImageNft { name: String, nft: Option<NFT> },
72 UpdateMetadata {
74 name: String,
75 metadata: Option<Metadata>,
76 },
77 AddTextRecord { name: String, record: TextRecord },
79 RemoveTextRecord { name: String, record_name: String },
81 UpdateTextRecord { name: String, record: TextRecord },
83 VerifyTextRecord {
85 name: String,
86 record_name: String,
87 result: bool,
88 },
89 UpdateVerifier { verifier: Option<String> },
91}
92
93#[cw_serde]
94#[derive(QueryResponses)]
95pub enum SgNameQueryMsg {
96 #[returns(String)]
99 Name { address: String },
100 #[returns(Addr)]
101 NameMarketplace {},
102 #[returns(String)]
103 AssociatedAddress { name: String },
104 #[returns(Option<NFT>)]
105 ImageNFT { name: String },
106 #[returns(Vec<TextRecord>)]
107 TextRecords { name: String },
108 #[returns(bool)]
109 IsTwitterVerified { name: String },
110}
111
112#[cfg(test)]
113mod test {
114 use super::*;
115
116 #[test]
117 fn encode_nft() {
118 let nft = NFT {
119 collection: Addr::unchecked("stars1y54exmx84cqtasvjnskf9f63djuuj68p2th570"),
120 token_id: "1".to_string(),
121 };
122 let json = nft.into_json_string();
123 assert_eq!(
124 json,
125 r#"{"collection":"stars1y54exmx84cqtasvjnskf9f63djuuj68p2th570","token_id":"1"}"#
126 );
127 }
128
129 #[test]
130 fn encode_text_record() {
131 let mut record = TextRecord::new("twitter", "shan3v");
132 let json = record.into_json_string();
133 assert_eq!(
134 json,
135 r#"{"name":"twitter","value":"shan3v","verified":null}"#
136 );
137
138 record.verified = Some(true);
139
140 let json = record.into_json_string();
141 assert_eq!(
142 json,
143 r#"{"name":"twitter","value":"shan3v","verified":true}"#
144 );
145
146 record.verified = Some(false);
147
148 let json = record.into_json_string();
149 assert_eq!(
150 json,
151 r#"{"name":"twitter","value":"shan3v","verified":false}"#
152 );
153 }
154
155 #[test]
156 fn encode_metadata() {
157 let image_nft = Some(NFT {
158 collection: Addr::unchecked("stars1y54exmx84cqtasvjnskf9f63djuuj68p2th570"),
159 token_id: "1".to_string(),
160 });
161 let record_1 = TextRecord::new("twitter", "shan3v");
162 let mut record_2 = TextRecord::new("discord", "shan3v");
163 record_2.verified = Some(true);
164 let records = vec![record_1, record_2];
165 let metadata = Metadata { image_nft, records };
166
167 let json = metadata.into_json_string();
168 assert_eq!(
169 json,
170 r#"{"image_nft":{"collection":"stars1y54exmx84cqtasvjnskf9f63djuuj68p2th570","token_id":"1"},"records":[{"name":"twitter","value":"shan3v","verified":null},{"name":"discord","value":"shan3v","verified":true}]}"#,
171 );
172 }
173}