archid_registry/
write_utils.rs

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    // println!("{:?}", &current_metadata);
35    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// can be used to mint and update resolver for non minted
249
250#[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}