desmos_bindings/profiles/
msg.rs

1//! Contains the messages that can be sent to the Desmos blockchain to interact with the x/profiles module.
2
3use crate::cosmos_types::Height;
4use crate::profiles::types::AddressData;
5use crate::profiles::types::*;
6use cosmwasm_std::Addr;
7
8/// ProfilesMsg is the builder to generate Desmos x/profiles messages.
9pub struct ProfilesMsg {}
10
11impl ProfilesMsg {
12    /// Creates an instance of [`MsgSaveProfile`].
13    /// * `dtag` - Unique profile tag, set None if editing the profile without modifying this field.
14    /// * `nickname` - Human readable name of the profile.
15    /// It will not change the current profile nickname if set this field to `None`.
16    /// * `bio` - Biography of the profile. It will not change the current profile bio if set this field to `None`.
17    /// * `profile_picture` - URL to the profile picture.
18    /// It will not change the current profile profile picture if set this field to `None`.
19    /// * `cover_picture` - URL to the cover cover picture.
20    /// It will not change the current profile cover picture if set this field to `None`.
21    /// * `creator` - Address of which is creating the profile.
22    pub fn save_profile(
23        dtag: Option<&str>,
24        nickname: Option<&str>,
25        bio: Option<&str>,
26        profile_picture: Option<&str>,
27        cover_picture: Option<&str>,
28        creator: Addr,
29    ) -> MsgSaveProfile {
30        MsgSaveProfile {
31            dtag: dtag.unwrap_or("[do-not-modify]").into(),
32            creator: creator.into(),
33            nickname: nickname.unwrap_or("[do-not-modify]").into(),
34            bio: bio.unwrap_or("[do-not-modify]").into(),
35            profile_picture: profile_picture.unwrap_or("[do-not-modify]").into(),
36            cover_picture: cover_picture.unwrap_or("[do-not-modify]").into(),
37        }
38    }
39
40    /// Creates an instance of [`MsgDeleteProfile`].
41    ///
42    /// * `creator` - Address of the profile to delete.
43    pub fn delete_profile(creator: Addr) -> MsgDeleteProfile {
44        MsgDeleteProfile {
45            creator: creator.into(),
46        }
47    }
48
49    /// Creates an instance of [`MsgRequestDTagTransfer`].
50    ///
51    /// * `sender` - Address of who is going to send the DTag.
52    /// * `receiver` - Address of who is going to receive the DTag
53    pub fn request_dtag_transfer(sender: Addr, receiver: Addr) -> MsgRequestDTagTransfer {
54        MsgRequestDTagTransfer {
55            receiver: receiver.into(),
56            sender: sender.into(),
57        }
58    }
59
60    /// Creates an instance of [`MsgAcceptDTagTransferRequest`].
61    ///
62    /// * `new_dtag` - The DTag to accept.
63    /// * `sender` - Address of who has sent the DTag.
64    /// * `receiver` - Address of who is receiving the DTag.
65    pub fn accept_dtag_transfer_request(
66        new_dtag: &str,
67        sender: Addr,
68        receiver: Addr,
69    ) -> MsgAcceptDTagTransferRequest {
70        MsgAcceptDTagTransferRequest {
71            new_dtag: new_dtag.into(),
72            sender: sender.into(),
73            receiver: receiver.into(),
74        }
75    }
76
77    /// Creates an instance of [`MsgRefuseDTagTransferRequest`].
78    ///
79    /// * `sender` - Address of who has started the DTag transfer.
80    /// * `receiver` - Address of who was supposed to receive the DTag.
81    pub fn refuse_dtag_transfer_request(
82        sender: Addr,
83        receiver: Addr,
84    ) -> MsgRefuseDTagTransferRequest {
85        MsgRefuseDTagTransferRequest {
86            sender: sender.into(),
87            receiver: receiver.into(),
88        }
89    }
90
91    /// Creates an instance of [`MsgCancelDTagTransferRequest`].
92    ///
93    /// * `receiver` - Address of who was supposed to receive the DTag.
94    /// * `sender` - Address of who has started the DTag transfer.
95    pub fn cancel_dtag_transfer_request(
96        receiver: Addr,
97        sender: Addr,
98    ) -> MsgCancelDTagTransferRequest {
99        MsgCancelDTagTransferRequest {
100            receiver: receiver.into(),
101            sender: sender.into(),
102        }
103    }
104
105    /// Creates an instance of [`MsgLinkChainAccount`].
106    ///
107    /// * `chain_address` - Data of the external chain address to be connected
108    /// with the Desmos profile.
109    /// * `proof` - The ownership proof of the external chain address.
110    /// * `chain_config` - The configuration of the external chain.
111    /// * `signer` - Address associated with the profile to which link the external account.
112    pub fn link_chain_account(
113        chain_address: AddressData,
114        proof: Proof,
115        chain_config: ChainConfig,
116        signer: Addr,
117    ) -> MsgLinkChainAccount {
118        MsgLinkChainAccount {
119            chain_address: Some(chain_address.into()),
120            proof: Some(proof),
121            chain_config: Some(chain_config),
122            signer: signer.into(),
123        }
124    }
125
126    /// Creates an instance of [`MsgUnlinkChainAccount`].
127    ///
128    /// * `owner` - The profile address from which to remove the link.
129    /// * `chain_name` - The chain name associated with the link to be removed.
130    /// * `target` - The external address to be removed.
131    pub fn unlink_chain_account(
132        owner: Addr,
133        chain_name: &str,
134        target: &str,
135    ) -> MsgUnlinkChainAccount {
136        MsgUnlinkChainAccount {
137            owner: owner.into(),
138            chain_name: chain_name.into(),
139            target: target.into(),
140        }
141    }
142
143    /// Creates an instance of [`MsgSetDefaultExternalAddress`].
144    ///
145    /// * `chain_name` - The chain name associated with the link to be set as default one.
146    /// * `target` - The external address to be set as default one.
147    /// * `signer` - The profile address which to set a default external address.
148    pub fn set_default_external_address(
149        chain_name: &str,
150        target: &str,
151        signer: Addr,
152    ) -> MsgSetDefaultExternalAddress {
153        MsgSetDefaultExternalAddress {
154            chain_name: chain_name.into(),
155            target: target.into(),
156            signer: signer.into(),
157        }
158    }
159
160    /// Creates an instance of [`MsgLinkApplication`].
161    ///
162    /// * `sender` - Sender of the connection request.
163    /// * `link_data` - The data related to the application to which connect.
164    /// * `call_data` - Hex encoded call data that will be sent to the data source in order to
165    /// verify the link.
166    /// * `source_port` - The port on which the packet will be sent.
167    /// * `source_channel` - The channel by which the packet will be sent.
168    /// * `timeout_height` - Timeout height relative to the current block height.
169    /// The timeout is disabled when set to 0.
170    /// * `timeout_timestamp` - Timeout timestamp (in nanoseconds) relative to the current block timestamp.
171    /// The timeout is disabled when set to 0.
172    pub fn link_application(
173        sender: Addr,
174        link_data: Data,
175        call_data: String,
176        source_port: String,
177        source_channel: String,
178        timeout_height: Height,
179        timeout_timestamp: u64,
180    ) -> MsgLinkApplication {
181        MsgLinkApplication {
182            sender: sender.into(),
183            link_data: Some(link_data),
184            call_data,
185            source_port,
186            source_channel,
187            timeout_height: Some(timeout_height),
188            timeout_timestamp: timeout_timestamp,
189        }
190    }
191
192    /// Creates an instance of [`MsgUnlinkApplication`].
193    ///
194    /// * `application` - The name of the application to unlink.
195    /// * `username` - The username inside the application to unlink.
196    /// * `signer` - The Desmos account from which the application should be unlinked.
197    pub fn unlink_application(
198        application: &str,
199        username: &str,
200        signer: Addr,
201    ) -> MsgUnlinkApplication {
202        MsgUnlinkApplication {
203            application: application.into(),
204            username: username.into(),
205            signer: signer.into(),
206        }
207    }
208}
209
210#[cfg(test)]
211mod tests {
212    use super::*;
213    use crate::cosmos_types::secp256k1;
214    use cosmwasm_std::Binary;
215
216    #[test]
217    fn test_save_profile() {
218        let msg = ProfilesMsg::save_profile(
219            Some("test"),
220            None,
221            None,
222            None,
223            None,
224            Addr::unchecked("user"),
225        );
226
227        let expected = MsgSaveProfile {
228            dtag: "test".into(),
229            nickname: "[do-not-modify]".into(),
230            bio: "[do-not-modify]".into(),
231            profile_picture: "[do-not-modify]".into(),
232            cover_picture: "[do-not-modify]".into(),
233            creator: "user".into(),
234        };
235
236        assert_eq!(expected, msg)
237    }
238
239    #[test]
240    fn test_delete_profile() {
241        let msg = ProfilesMsg::delete_profile(Addr::unchecked("user"));
242
243        let expected = MsgDeleteProfile {
244            creator: "user".into(),
245        };
246
247        assert_eq!(expected, msg)
248    }
249
250    #[test]
251    fn test_request_dtag_transfer() {
252        let msg = ProfilesMsg::request_dtag_transfer(
253            Addr::unchecked("user"),
254            Addr::unchecked("reciever"),
255        );
256
257        let expected = MsgRequestDTagTransfer {
258            sender: "user".into(),
259            receiver: "reciever".into(),
260        };
261
262        assert_eq!(expected, msg)
263    }
264
265    #[test]
266    fn test_accept_dtag_transfer_request() {
267        let msg = ProfilesMsg::accept_dtag_transfer_request(
268            "test",
269            Addr::unchecked("reciever"),
270            Addr::unchecked("user"),
271        );
272
273        let expected = MsgAcceptDTagTransferRequest {
274            new_dtag: "test".into(),
275            sender: "reciever".into(),
276            receiver: "user".into(),
277        };
278
279        assert_eq!(expected, msg)
280    }
281
282    #[test]
283    fn test_refuse_dtag_transfer_request() {
284        let msg = ProfilesMsg::refuse_dtag_transfer_request(
285            Addr::unchecked("reciever"),
286            Addr::unchecked("user"),
287        );
288
289        let expected = MsgRefuseDTagTransferRequest {
290            sender: "reciever".into(),
291            receiver: "user".into(),
292        };
293
294        assert_eq!(expected, msg)
295    }
296
297    #[test]
298    fn test_cancel_dtag_transfer_request() {
299        let msg = ProfilesMsg::cancel_dtag_transfer_request(
300            Addr::unchecked("reciever"),
301            Addr::unchecked("user"),
302        );
303
304        let expected = MsgCancelDTagTransferRequest {
305            receiver: "reciever".into(),
306            sender: "user".into(),
307        };
308
309        assert_eq!(expected, msg)
310    }
311
312    #[test]
313    fn test_link_chain_account() {
314        let chain_addr = AddressData::Bech32Address(Bech32Address {
315            value: "cosmos18xnmlzqrqr6zt526pnczxe65zk3f4xgmndpxn2".to_string(),
316            prefix: "cosmos".to_string(),
317        });
318
319        let proof = Proof {
320            pub_key: Some(secp256k1::PubKey {
321                key: Binary::from_base64("ArlRm0a5fFTHFfKha1LpDd+g3kZlyRBBF4R8PSM8Zo4Y").unwrap().to_vec(),
322            }.into()),
323            signature: Some(SingleSignature{
324                value_type: SignatureValueType::Raw.into(),
325                signature: Binary::from_base64("C7xppu4C4S3dgeC9TVqhyGN1hbMnMbnmWgXQI2WE8t0oHIHhDTqXyZgzhNNYiBO7ulno3G8EXO3Ep5KMFngyFg").unwrap().to_vec(),
326            }.into()),
327            plain_text: "636f736d6f733138786e6d6c7a71727172367a74353236706e637a786536357a6b33663478676d6e6470786e32".to_string(),
328        };
329
330        let chain_config = ChainConfig {
331            name: "cosmos".to_string(),
332        };
333
334        let msg = ProfilesMsg::link_chain_account(
335            chain_addr.clone(),
336            proof.clone(),
337            chain_config.clone(),
338            Addr::unchecked("cosmos18xnmlzqrqr6zt526pnczxe65zk3f4xgmndpxn2"),
339        );
340
341        let expected = MsgLinkChainAccount {
342            chain_address: Some(chain_addr.clone().into()),
343            proof: Some(proof),
344            chain_config: Some(chain_config),
345            signer: "cosmos18xnmlzqrqr6zt526pnczxe65zk3f4xgmndpxn2".into(),
346        };
347
348        assert_eq!(expected, msg)
349    }
350
351    #[test]
352    fn test_unlink_chain_account() {
353        let msg = ProfilesMsg::unlink_chain_account(Addr::unchecked("owner"), "cosmos", "target");
354
355        let expected = MsgUnlinkChainAccount {
356            owner: "owner".into(),
357            chain_name: "cosmos".into(),
358            target: "target".into(),
359        };
360
361        assert_eq!(expected, msg)
362    }
363
364    #[test]
365    fn test_set_default_external_address() {
366        let msg =
367            ProfilesMsg::set_default_external_address("cosmos", "target", Addr::unchecked("owner"));
368
369        let expected = MsgSetDefaultExternalAddress {
370            chain_name: "cosmos".into(),
371            target: "target".into(),
372            signer: "owner".into(),
373        };
374
375        assert_eq!(expected, msg)
376    }
377
378    #[test]
379    fn test_link_application() {
380        let data = Data {
381            application: "twitter".into(),
382            username: "goldrake".into(),
383        };
384
385        let oracle_req = OracleRequest {
386            id: 537807,
387            oracle_script_id: 32,
388            call_data: Some(oracle_request::CallData {
389                application: "twitter".into(),
390                call_data: "7b22757365726e616d65223a224c756361675f5f2335323337227d".into(),
391            }),
392            client_id: "desmos1nwp8gxrnmrsrzjdhvk47vvmthzxjtphgxp5ftc-twitter-goldrake".into(),
393        };
394
395        let timeout_height = Height {
396            revision_number: 0,
397            revision_height: 0,
398        };
399
400        let msg = ProfilesMsg::link_application(
401            Addr::unchecked("owner"),
402            data.clone(),
403            oracle_req.call_data.clone().unwrap().call_data,
404            "123".into(),
405            "123".into(),
406            timeout_height.clone(),
407            1,
408        );
409
410        let expected = MsgLinkApplication {
411            sender: "owner".into(),
412            link_data: Some(data),
413            call_data: oracle_req.call_data.unwrap().call_data,
414            source_port: "123".into(),
415            source_channel: "123".into(),
416            timeout_height: Some(timeout_height),
417            timeout_timestamp: 1,
418        };
419
420        assert_eq!(expected, msg);
421    }
422
423    #[test]
424    fn test_unlink_application() {
425        let msg = ProfilesMsg::unlink_application("twitter", "gawrgura", Addr::unchecked("owner"));
426
427        let expected = MsgUnlinkApplication {
428            application: "twitter".into(),
429            username: "gawrgura".into(),
430            signer: "owner".into(),
431        };
432
433        assert_eq!(expected, msg)
434    }
435}