1use cosmwasm_std::{
2 to_json_binary, Addr, BankMsg, Coin, CosmosMsg, DepsMut, Env, StdResult, Uint128, WasmMsg,
3};
4
5use crate::read_utils::get_name_body;
6use crate::read_utils::query_current_metadata;
7use crate::state::{resolver, NameRecord};
8use archid_token::{
9 ExecuteMsg as Cw721ExecuteMsg, Metadata, MintMsg, Subdomain, UpdateMetadataMsg,
10};
11
12pub static DENOM: &str = "aarch";
13
14#[allow(clippy::too_many_arguments)]
15pub fn add_subdomain_metadata(
16 deps: &DepsMut,
17 cw721: &Addr,
18 name: String,
19 subdomain: String,
20 resolver: Addr,
21 created: u64,
22 expiry: u64,
23) -> StdResult<CosmosMsg> {
24 let mut current_metadata: Metadata = query_current_metadata(&name, cw721, deps).unwrap();
25 let mut subdomains: Vec<Subdomain> = current_metadata.subdomains.as_ref().unwrap().clone();
26 subdomains.push(Subdomain {
27 name: Some(subdomain),
28 resolver: Some(resolver),
29 minted: None,
30 created: Some(created),
31 expiry: Some(expiry),
32 });
33 current_metadata.subdomains = Some((*subdomains).to_vec());
34 let resp = send_data_update(&name, cw721, current_metadata)?;
36 Ok(resp)
37}
38pub fn update_subdomain_metadata(
39 deps: &DepsMut,
40 cw721: &Addr,
41 domain: &String,
42 subdomain: &String,
43 resolver: Addr,
44 expiry: u64,
45) -> StdResult<CosmosMsg> {
46 let mut current_metadata: Metadata = query_current_metadata(domain, cw721, deps).unwrap();
47 let mut subdomains: Vec<Subdomain> = current_metadata.subdomains.as_ref().unwrap().clone();
48 let index = subdomains
49 .iter()
50 .position(|r| &r.clone().name.unwrap() == subdomain)
51 .unwrap();
52 subdomains[index].expiry = Some(expiry);
53 subdomains[index].minted = None;
54 subdomains[index].resolver = Some(resolver);
55 current_metadata.subdomains = Some((*subdomains).to_vec());
56 let resp = send_data_update(domain, cw721, current_metadata)?;
57 Ok(resp)
58}
59pub fn update_subdomain_expiry(
60 nft: Addr,
61 deps: DepsMut,
62 domain: String,
63 subdomain: String,
64 expiration: u64,
65) -> StdResult<Vec<CosmosMsg>> {
66 let mut messages = Vec::new();
67 let domain_route: String = format!("{}.{}", subdomain, domain);
68 let key = domain_route.as_bytes();
69 let domain_config: NameRecord = (resolver(deps.storage).may_load(key)?).unwrap();
70 let record = NameRecord {
71 resolver: domain_config.resolver.clone(),
72 created: domain_config.created,
73 expiration,
74 };
75 resolver(deps.storage).save(key, &record)?;
76 let msg = update_subdomain_metadata(
77 &deps,
78 &nft,
79 &domain,
80 &subdomain,
81 domain_config.resolver,
82 expiration,
83 )?;
84 messages.push(msg);
85
86 Ok(messages)
87}
88pub fn remove_subdomain_metadata(
89 deps: &DepsMut,
90 cw721: &Addr,
91 name: String,
92 subdomain: String,
93) -> StdResult<CosmosMsg> {
94 let mut current_metadata: Metadata = query_current_metadata(&name, cw721, deps).unwrap();
95 let mut subdomains = current_metadata.subdomains.as_ref().unwrap().clone();
96
97 subdomains.retain(|item| item.name.as_ref().unwrap().as_bytes() != subdomain.as_bytes());
98 current_metadata.subdomains = Some((*subdomains).to_vec());
99 let resp = send_data_update(&name, cw721, current_metadata)?;
100 Ok(resp)
101}
102
103pub fn mint_handler(
104 name: &String,
105 creator: &Addr,
106 cw721: &Addr,
107 created: u64,
108 expiration: u64,
109) -> StdResult<CosmosMsg> {
110 let body = get_name_body(name.to_string());
111 let subdomains = if body.contains('.') {
112 None
113 } else {
114 Some(vec![])
115 };
116 let accounts = if body.contains('.') {
117 None
118 } else {
119 Some(vec![])
120 };
121 let websites = if body.contains('.') {
122 None
123 } else {
124 Some(vec![])
125 };
126 let description = if body.contains('.') {
127 [name, " subdomain"].concat()
128 } else {
129 [name, " domain"].concat()
130 };
131
132 let mint_extension = Some(Metadata {
133 description: Some(description),
134 name: Some(body),
135 image: None,
136 created: Some(created),
137 expiry: Some(expiration),
138 domain: Some(name.clone()),
139 subdomains,
140 accounts,
141 websites,
142 });
143
144 let mint_msg: archid_token::ExecuteMsg = Cw721ExecuteMsg::Mint(MintMsg {
145 token_id: name.to_string(),
146 owner: creator.to_string(),
147 token_uri: None,
148 extension: mint_extension,
149 });
150
151 let resp: CosmosMsg = WasmMsg::Execute {
152 contract_addr: cw721.to_string(),
153 msg: to_json_binary(&mint_msg)?,
154 funds: vec![],
155 }
156 .into();
157 Ok(resp)
158}
159
160pub fn burn_handler(name: &String, cw721: &Addr) -> StdResult<CosmosMsg> {
161 let burn_msg: Cw721ExecuteMsg = Cw721ExecuteMsg::Burn {
162 token_id: name.to_string(),
163 };
164 let resp: CosmosMsg = WasmMsg::Execute {
165 contract_addr: cw721.to_string(),
166 msg: to_json_binary(&burn_msg)?,
167 funds: vec![],
168 }
169 .into();
170 Ok(resp)
171}
172
173pub fn send_tokens(to: &Addr, amount: Uint128) -> StdResult<CosmosMsg> {
174 let msg = BankMsg::Send {
175 to_address: to.into(),
176 amount: ([Coin {
177 denom: String::from(DENOM),
178 amount,
179 }])
180 .to_vec(),
181 };
182 Ok(msg.into())
183}
184
185pub fn send_data_update(name: &String, cw721: &Addr, data: Metadata) -> StdResult<CosmosMsg> {
186 let update = Cw721ExecuteMsg::UpdateMetadata(UpdateMetadataMsg {
187 token_id: name.to_string(),
188 extension: Some(data),
189 });
190 let resp: CosmosMsg = WasmMsg::Execute {
191 contract_addr: cw721.to_string(),
192 msg: to_json_binary(&update)?,
193 funds: vec![],
194 }
195 .into();
196 Ok(resp)
197}
198pub fn update_metadata_expiry(
199 deps: DepsMut,
200 cw721: &Addr,
201 name: String,
202 expiration: u64,
203) -> StdResult<CosmosMsg> {
204 let mut current_metadata: Metadata = query_current_metadata(&name, cw721, &deps).unwrap();
205 current_metadata.expiry = Some(expiration);
206 let resp = send_data_update(&name, cw721, current_metadata)?;
207 Ok(resp)
208}
209
210#[allow(clippy::too_many_arguments)]
211pub fn register_new_subdomain(
212 nft: Addr,
213 deps: DepsMut,
214 env: Env,
215 domain: String,
216 subdomain: String,
217 new_resolver: Addr,
218 new_owner: Addr,
219 expiration: u64,
220) -> StdResult<Vec<CosmosMsg>> {
221 let domain_route: String = format!("{}.{}", subdomain, domain);
222 let key = domain_route.as_bytes();
223 let mut messages = Vec::new();
224 let created = env.block.time.seconds();
225
226 let metadata_msg = add_subdomain_metadata(
227 &deps,
228 &nft,
229 domain,
230 subdomain,
231 new_resolver.clone(),
232 env.block.time.seconds(),
233 expiration,
234 )?;
235 messages.push(metadata_msg);
236 let record = NameRecord {
237 resolver: new_resolver,
238 created,
239 expiration,
240 };
241 resolver(deps.storage).save(key, &record)?;
242
243 let resp = mint_handler(&domain_route, &new_owner, &nft, created, expiration)?;
244 messages.push(resp);
245
246 Ok(messages)
247}
248#[allow(clippy::too_many_arguments)]
251pub fn burn_remint_subdomain(
252 deps: DepsMut,
253 nft: Addr,
254 env: Env,
255 domain: String,
256 subdomain: String,
257 new_resolver: Addr,
258 new_owner: Addr,
259 expiration: u64,
260) -> StdResult<Vec<CosmosMsg>> {
261 let domain_route: String = format!("{}.{}", subdomain, domain);
262 let key = domain_route.as_bytes();
263 let mut messages = Vec::new();
264 let created = env.block.time.seconds();
265 let burn_msg = burn_handler(&format!("{}.{}", subdomain, domain), &nft)?;
266 messages.push(burn_msg);
267
268 let metadata_msg = add_subdomain_metadata(
269 &deps,
270 &nft,
271 domain,
272 subdomain,
273 new_resolver.clone(),
274 env.block.time.seconds(),
275 expiration,
276 )?;
277 messages.push(metadata_msg);
278 let record = NameRecord {
279 resolver: new_resolver,
280 created,
281 expiration,
282 };
283 resolver(deps.storage).save(key, &record)?;
284
285 let resp = mint_handler(&domain_route, &new_owner, &nft, created, expiration)?;
286 messages.push(resp);
287
288 Ok(messages)
289}