provwasm_stdv1/msg.rs
1use cosmwasm_std::{
2 coin, to_binary, Addr, Binary, Coin, CosmosMsg, CustomMsg, StdError, StdResult,
3};
4use schemars::JsonSchema;
5use serde::{Deserialize, Serialize};
6
7use crate::common::{validate_address, validate_string};
8use crate::types::{AttributeValueType, MarkerAccess, MarkerType, NameBinding, ProvenanceRoute};
9use crate::Scope;
10
11// The data format version to pass into provenance for message encoding
12static MSG_DATAFMT_VERSION: &str = "2.0.0";
13
14/// Represents a request to encode custom provenance messages.
15#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, JsonSchema)]
16#[serde(rename_all = "snake_case")]
17pub struct ProvenanceMsg {
18 pub route: ProvenanceRoute, // The module router key
19 pub params: ProvenanceMsgParams, // The module-specific encoder params
20 pub version: String, // The data format version
21}
22
23impl CustomMsg for ProvenanceMsg {}
24
25/// Input params for custom provenance message encoders.
26#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, JsonSchema)]
27pub enum ProvenanceMsgParams {
28 Name(NameMsgParams),
29 Attribute(AttributeMsgParams),
30 Marker(MarkerMsgParams),
31 Metadata(MetadataMsgParams),
32 MsgFees(MsgFeesMsgParams),
33}
34
35/// Input params for creating name module messages.
36#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, JsonSchema)]
37#[serde(rename_all = "snake_case")]
38pub enum NameMsgParams {
39 BindName {
40 name: String,
41 address: Addr,
42 restrict: bool,
43 },
44 DeleteName {
45 name: String,
46 },
47}
48
49// Create a custom cosmos message using name module params.
50fn create_name_msg(params: NameMsgParams) -> CosmosMsg<ProvenanceMsg> {
51 CosmosMsg::Custom(ProvenanceMsg {
52 route: ProvenanceRoute::Name,
53 params: ProvenanceMsgParams::Name(params),
54 version: String::from(MSG_DATAFMT_VERSION),
55 })
56}
57
58/// Create a message that will bind a name to an address.
59///
60/// ### Example
61///
62/// ```rust
63/// // Imports required
64/// use cosmwasm_std::{Addr, Response, StdResult};
65/// use provwasm_std::{bind_name, NameBinding, ProvenanceMsg};
66///
67/// // Bind a name to an address.
68/// fn exec_bind_name(
69/// name: String,
70/// address: Addr,
71/// ) -> StdResult<Response<ProvenanceMsg>> {
72/// let msg = bind_name(&name, address, NameBinding::Restricted)?;
73/// let mut res = Response::new().add_message(msg);
74/// Ok(res)
75/// }
76/// ```
77pub fn bind_name<S: Into<String>, H: Into<Addr>>(
78 name: S,
79 address: H,
80 binding: NameBinding,
81) -> StdResult<CosmosMsg<ProvenanceMsg>> {
82 Ok(create_name_msg(NameMsgParams::BindName {
83 name: validate_string(name, "name")?,
84 address: validate_address(address)?,
85 restrict: matches!(binding, NameBinding::Restricted),
86 }))
87}
88
89/// Create a message that will un-bind a name from an address.
90///
91/// ### Example
92///
93/// ```rust
94/// // Imports required
95/// use cosmwasm_std::{Response, StdResult};
96/// use provwasm_std::{unbind_name, ProvenanceMsg};
97///
98/// // Unbind a name
99/// fn exec_unbind_name(name: String) -> StdResult<Response<ProvenanceMsg>> {
100/// let msg = unbind_name(&name)?;
101/// let mut res = Response::new().add_message(msg);
102/// Ok(res)
103/// }
104/// ```
105pub fn unbind_name<S: Into<String>>(name: S) -> StdResult<CosmosMsg<ProvenanceMsg>> {
106 Ok(create_name_msg(NameMsgParams::DeleteName {
107 name: validate_string(name, "name")?,
108 }))
109}
110
111/// Input params for creating attribute module messages.
112#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, JsonSchema)]
113#[serde(rename_all = "snake_case")]
114pub enum AttributeMsgParams {
115 AddAttribute {
116 address: Addr,
117 name: String,
118 value: Binary,
119 value_type: AttributeValueType,
120 },
121 DeleteAttribute {
122 address: Addr,
123 name: String,
124 },
125 DeleteDistinctAttribute {
126 address: Addr,
127 name: String,
128 value: Binary,
129 },
130 UpdateAttribute {
131 address: Addr,
132 name: String,
133 original_value: Binary,
134 original_value_type: AttributeValueType,
135 update_value: Binary,
136 update_value_type: AttributeValueType,
137 },
138}
139
140// Create a custom cosmos message using attribute module params.
141fn create_attribute_msg(params: AttributeMsgParams) -> CosmosMsg<ProvenanceMsg> {
142 CosmosMsg::Custom(ProvenanceMsg {
143 route: ProvenanceRoute::Attribute,
144 params: ProvenanceMsgParams::Attribute(params),
145 version: String::from(MSG_DATAFMT_VERSION),
146 })
147}
148
149/// Create a message that will add an attribute (a typed key-value pair) to an account.
150///
151/// ### Example
152///
153/// ```rust
154/// // Imports required
155/// use cosmwasm_std::{Binary, Env, Addr, Response, StdResult};
156/// use provwasm_std::{add_attribute, AttributeValueType, ProvenanceMsg};
157///
158/// // Add a greeting attribute to an account.
159/// // NOTE: The name below must resolve to the contract address.
160/// fn exec_add_greeting(
161/// env: Env,
162/// address: Addr,
163/// text: String,
164/// ) -> StdResult<Response<ProvenanceMsg>> {
165/// let attr_name = String::from("greeting.my-contract.sc.pb");
166/// let greeting = String::from("hello");
167/// let msg = add_attribute(
168/// address,
169/// &attr_name,
170/// Binary::from(greeting.as_bytes()),
171/// AttributeValueType::String,
172/// )?;
173/// let mut res = Response::new().add_message(msg);
174/// Ok(res)
175/// }
176/// ```
177pub fn add_attribute<H: Into<Addr>, S: Into<String>, B: Into<Binary>>(
178 address: H,
179 name: S,
180 value: B,
181 value_type: AttributeValueType,
182) -> StdResult<CosmosMsg<ProvenanceMsg>> {
183 if value_type == AttributeValueType::Unspecified {
184 return Err(StdError::generic_err(
185 "cannot add attribute with unspecified value type",
186 ));
187 }
188 Ok(create_attribute_msg(AttributeMsgParams::AddAttribute {
189 address: validate_address(address)?,
190 name: validate_string(name, "name")?,
191 value: value.into(),
192 value_type,
193 }))
194}
195
196/// Create a message that will add a JSON attribute to an account. Serializable types can be passed
197/// into this function, but it's up to the user to handle StdResult error case.
198///
199/// ### Example
200///
201/// ```rust
202/// // Imports required
203/// use cosmwasm_std::{Env, Addr, Response, StdResult};
204/// use provwasm_std::{add_json_attribute, ProvenanceMsg};
205/// use schemars::JsonSchema;
206/// use serde::{Deserialize, Serialize};
207///
208/// // Add a label attribute. NOTE: The name below must resolve to the contract address.
209/// fn exec_add_label(
210/// env: Env,
211/// address: Addr,
212/// text: String,
213/// ) -> StdResult<Response<ProvenanceMsg>> {
214/// let attr_name = String::from("label.my-contract.sc.pb");
215/// let timestamp = env.block.time.nanos();
216/// let label = Label { text, timestamp };
217/// let msg = add_json_attribute(address, &attr_name, &label)?;
218/// let mut res = Response::new().add_message(msg);
219/// Ok(res)
220/// }
221///
222/// // Text with a timestamp.
223/// #[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, JsonSchema)]
224/// #[serde(rename_all = "snake_case")]
225/// pub struct Label {
226/// pub text: String,
227/// pub timestamp: u64,
228/// }
229///
230/// ```
231pub fn add_json_attribute<H: Into<Addr>, S: Into<String>, T: Serialize + ?Sized>(
232 address: H,
233 name: S,
234 data: &T,
235) -> StdResult<CosmosMsg<ProvenanceMsg>> {
236 // Serialize the value, bailing on error
237 let value = to_binary(data)?;
238 // Create and return json typed message
239 add_attribute(address, name, value, AttributeValueType::Json)
240}
241
242/// Create a message that will remove all attributes with the given name from an account.
243///
244/// ### Example
245///
246/// ```rust
247/// // Imports required
248/// use cosmwasm_std::{Addr, Response, StdResult};
249/// use provwasm_std::{delete_attributes, ProvenanceMsg};
250///
251/// // Delete all label attributes. NOTE: The name below must resolve to the contract address.
252/// fn exec_delete_labels(
253/// address: Addr,
254/// ) -> StdResult<Response<ProvenanceMsg>> {
255/// let attr_name = String::from("label.my-contract.sc.pb");
256/// let msg = delete_attributes(address, &attr_name)?;
257/// let mut res = Response::new().add_message(msg);
258/// Ok(res)
259/// }
260/// ```
261pub fn delete_attributes<H: Into<Addr>, S: Into<String>>(
262 address: H,
263 name: S,
264) -> StdResult<CosmosMsg<ProvenanceMsg>> {
265 Ok(create_attribute_msg(AttributeMsgParams::DeleteAttribute {
266 address: validate_address(address)?,
267 name: validate_string(name, "name")?,
268 }))
269}
270
271/// Create a message that will delete a distinct attribute with the given name and value from an account.
272///
273/// ### Example
274///
275/// ```rust
276/// // Imports required
277/// use cosmwasm_std::{Addr, Response, StdResult, to_binary};
278/// use provwasm_std::{delete_distinct_attribute, ProvenanceMsg};
279///
280/// // Delete the distinct label attribute. NOTE: The name below must resolve to the contract address.
281/// fn try_delete_distinct_label(
282/// address: Addr,
283/// ) -> StdResult<Response<ProvenanceMsg>> {
284/// let attr_name = String::from("label.my-contract.sc.pb");
285/// let attr_value = String::from("hello");
286/// let msg = delete_distinct_attribute(address, &attr_name, to_binary(&attr_value)?)?;
287/// let mut res = Response::new().add_message(msg);
288/// Ok(res)
289/// }
290/// ```
291pub fn delete_distinct_attribute<H: Into<Addr>, S: Into<String>, B: Into<Binary>>(
292 address: H,
293 name: S,
294 value: B,
295) -> StdResult<CosmosMsg<ProvenanceMsg>> {
296 Ok(create_attribute_msg(
297 AttributeMsgParams::DeleteDistinctAttribute {
298 address: validate_address(address)?,
299 name: validate_string(name, "name")?,
300 value: value.into(),
301 },
302 ))
303}
304
305/// Create a message that will update an attribute (a typed key-value pair) on an account.
306///
307/// ### Example
308///
309/// ```rust
310/// // Imports required
311/// use cosmwasm_std::{Binary, Env, Addr, Response, StdResult};
312/// use provwasm_std::{update_attribute, AttributeValueType, ProvenanceMsg};
313///
314/// // Update an attribute on an account.
315/// // NOTE: The name below must resolve to the contract address.
316/// fn try_update_attribute(
317/// env: Env,
318/// address: Addr,
319/// text: String,
320/// ) -> StdResult<Response<ProvenanceMsg>> {
321/// let attr_name = String::from("attribute.my-contract.sc.pb");
322/// let original_attribute_value = String::from("hello");
323/// let updated_attribute_value = String::from("goodbye");
324/// let msg = update_attribute(
325/// address,
326/// &attr_name,
327/// Binary::from(original_attribute_value.as_bytes()),
328/// AttributeValueType::String,
329/// Binary::from(original_attribute_value.as_bytes()),
330/// AttributeValueType::String,
331/// )?;
332/// let mut res = Response::new().add_message(msg);
333/// Ok(res)
334/// }
335/// ```
336pub fn update_attribute<H: Into<Addr>, S: Into<String>, B: Into<Binary>>(
337 address: H,
338 name: S,
339 original_value: B,
340 original_value_type: AttributeValueType,
341 update_value: B,
342 update_value_type: AttributeValueType,
343) -> StdResult<CosmosMsg<ProvenanceMsg>> {
344 if original_value_type == AttributeValueType::Unspecified {
345 return Err(StdError::generic_err(
346 "cannot update attribute with unspecified original value type",
347 ));
348 }
349 if update_value_type == AttributeValueType::Unspecified {
350 return Err(StdError::generic_err(
351 "cannot update attribute with unspecified update value type",
352 ));
353 }
354 Ok(create_attribute_msg(AttributeMsgParams::UpdateAttribute {
355 address: validate_address(address)?,
356 name: validate_string(name, "name")?,
357 original_value: original_value.into(),
358 original_value_type,
359 update_value: update_value.into(),
360 update_value_type,
361 }))
362}
363
364/// Input params for creating marker module messages.
365#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, JsonSchema)]
366#[serde(rename_all = "snake_case")]
367pub enum MarkerMsgParams {
368 CreateMarker {
369 coin: Coin,
370 marker_type: MarkerType,
371 },
372 GrantMarkerAccess {
373 denom: String,
374 address: Addr,
375 permissions: Vec<MarkerAccess>,
376 },
377 RevokeMarkerAccess {
378 denom: String,
379 address: Addr,
380 },
381 FinalizeMarker {
382 denom: String,
383 },
384 ActivateMarker {
385 denom: String,
386 },
387 CancelMarker {
388 denom: String,
389 },
390 DestroyMarker {
391 denom: String,
392 },
393 MintMarkerSupply {
394 coin: Coin,
395 },
396 BurnMarkerSupply {
397 coin: Coin,
398 },
399 WithdrawCoins {
400 marker_denom: String,
401 coin: Coin,
402 recipient: Addr,
403 },
404 TransferMarkerCoins {
405 coin: Coin,
406 to: Addr,
407 from: Addr,
408 },
409}
410
411// Create a custom cosmos message using marker module params.
412fn create_marker_msg(params: MarkerMsgParams) -> CosmosMsg<ProvenanceMsg> {
413 CosmosMsg::Custom(ProvenanceMsg {
414 route: ProvenanceRoute::Marker,
415 params: ProvenanceMsgParams::Marker(params),
416 version: String::from(MSG_DATAFMT_VERSION),
417 })
418}
419
420/// Create a message that will propose a new marker with a given type.
421///
422/// ### Example
423///
424/// ```rust
425/// // Imports required
426/// use cosmwasm_std::{Response, StdResult};
427/// use provwasm_std::{create_marker, MarkerType, ProvenanceMsg};
428///
429/// // Create and dispatch a message that will propose a new unrestricted marker.
430/// fn try_create_marker(
431/// amount: u128,
432/// denom: String,
433/// ) -> StdResult<Response<ProvenanceMsg>> {
434/// let msg = create_marker(amount, &denom, MarkerType::Coin)?;
435/// let mut res = Response::new().add_message(msg);
436/// Ok(res)
437/// }
438/// ```
439pub fn create_marker<S: Into<String>>(
440 amount: u128,
441 denom: S,
442 marker_type: MarkerType,
443) -> StdResult<CosmosMsg<ProvenanceMsg>> {
444 let coin = coin(amount, validate_string(denom, "denom")?);
445 Ok(create_marker_msg(MarkerMsgParams::CreateMarker {
446 coin,
447 marker_type,
448 }))
449}
450
451/// Create a message that will grant permissions on a marker.
452///
453/// ### Example
454///
455/// ```rust
456/// // Imports required
457/// use cosmwasm_std::{Addr, Response, StdResult};
458/// use provwasm_std::{grant_marker_access, MarkerAccess, ProvenanceMsg};
459///
460/// // Create and dispatch a message that will grant specific permissions to a marker for an address.
461/// fn try_grant_marker_access(
462/// denom: String,
463/// address: Addr,
464/// ) -> StdResult<Response<ProvenanceMsg>> {
465/// let permissions = vec![MarkerAccess::Burn, MarkerAccess::Mint];
466/// let msg = grant_marker_access(&denom, address, permissions)?;
467/// let mut res = Response::new().add_message(msg);
468/// Ok(res)
469/// }
470/// ```
471pub fn grant_marker_access<S: Into<String>, H: Into<Addr>>(
472 denom: S,
473 address: H,
474 permissions: Vec<MarkerAccess>,
475) -> StdResult<CosmosMsg<ProvenanceMsg>> {
476 Ok(create_marker_msg(MarkerMsgParams::GrantMarkerAccess {
477 denom: validate_string(denom, "denom")?,
478 address: validate_address(address)?,
479 permissions,
480 }))
481}
482
483/// Create a message that will revoke marker permissions.
484///
485/// ### Example
486///
487/// ```rust
488/// // Imports required
489/// use cosmwasm_std::{Addr, Response, StdResult};
490/// use provwasm_std::{revoke_marker_access, ProvenanceMsg};
491///
492/// // Create and dispatch a message that will revoke all permissions from a marker for an address.
493/// fn try_revoke_marker_access(
494/// denom: String,
495/// address: Addr,
496/// ) -> StdResult<Response<ProvenanceMsg>> {
497/// let msg = revoke_marker_access(&denom, address)?;
498/// let mut res = Response::new().add_message(msg);
499/// Ok(res)
500/// }
501/// ```
502pub fn revoke_marker_access<S: Into<String>, H: Into<Addr>>(
503 denom: S,
504 address: H,
505) -> StdResult<CosmosMsg<ProvenanceMsg>> {
506 Ok(create_marker_msg(MarkerMsgParams::RevokeMarkerAccess {
507 denom: validate_string(denom, "denom")?,
508 address: validate_address(address)?,
509 }))
510}
511
512/// Create a message that will finalize a proposed marker.
513///
514/// ### Example
515///
516/// ```rust
517/// // Imports required
518/// use cosmwasm_std::{Response, StdResult};
519/// use provwasm_std::{finalize_marker, ProvenanceMsg};
520///
521/// // Create and dispatch a message that will finalize a proposed marker.
522/// fn try_finalize_marker(denom: String) -> StdResult<Response<ProvenanceMsg>> {
523/// let msg = finalize_marker(&denom)?;
524/// let mut res = Response::new().add_message(msg);
525/// Ok(res)
526/// }
527/// ```
528pub fn finalize_marker<S: Into<String>>(denom: S) -> StdResult<CosmosMsg<ProvenanceMsg>> {
529 Ok(create_marker_msg(MarkerMsgParams::FinalizeMarker {
530 denom: validate_string(denom, "denom")?,
531 }))
532}
533
534/// Create a message that will activate a finalized marker.
535///
536/// ### Example
537///
538/// ```rust
539/// // Imports required
540/// use cosmwasm_std::{Response, StdResult};
541/// use provwasm_std::{activate_marker, ProvenanceMsg};
542///
543/// // Create and dispatch a message that will activate a finalized marker.
544/// fn try_activate_marker(denom: String) -> StdResult<Response<ProvenanceMsg>> {
545/// let msg = activate_marker(&denom)?;
546/// let mut res = Response::new().add_message(msg);
547/// Ok(res)
548/// }
549/// ```
550pub fn activate_marker<S: Into<String>>(denom: S) -> StdResult<CosmosMsg<ProvenanceMsg>> {
551 Ok(create_marker_msg(MarkerMsgParams::ActivateMarker {
552 denom: validate_string(denom, "denom")?,
553 }))
554}
555
556/// Create a message that will cancel a marker.
557///
558/// ### Example
559///
560/// ```rust
561/// // Imports required
562/// use cosmwasm_std::{Response, StdResult};
563/// use provwasm_std::{cancel_marker, ProvenanceMsg};
564///
565/// // Create and dispatch a message that will cancel a marker.
566/// fn try_cancel_marker(denom: String) -> StdResult<Response<ProvenanceMsg>> {
567/// let msg = cancel_marker(&denom)?;
568/// let mut res = Response::new().add_message(msg);
569/// Ok(res)
570/// }
571/// ```
572pub fn cancel_marker<S: Into<String>>(denom: S) -> StdResult<CosmosMsg<ProvenanceMsg>> {
573 Ok(create_marker_msg(MarkerMsgParams::CancelMarker {
574 denom: validate_string(denom, "denom")?,
575 }))
576}
577
578/// Create a message that will destroy a marker.
579///
580/// ### Example
581///
582/// ```rust
583/// // Imports required
584/// use cosmwasm_std::{Response, StdResult};
585/// use provwasm_std::{destroy_marker, ProvenanceMsg};
586///
587/// // Create and dispatch a message that will destroy a marker.
588/// fn try_destroy_marker(denom: String) -> StdResult<Response<ProvenanceMsg>> {
589/// let msg = destroy_marker(&denom)?;
590/// let mut res = Response::new().add_message(msg);
591/// Ok(res)
592/// }
593/// ```
594pub fn destroy_marker<S: Into<String>>(denom: S) -> StdResult<CosmosMsg<ProvenanceMsg>> {
595 Ok(create_marker_msg(MarkerMsgParams::DestroyMarker {
596 denom: validate_string(denom, "denom")?,
597 }))
598}
599
600/// Create a message that will mint marker coins.
601///
602/// ### Example
603///
604/// ```rust
605/// // Imports required
606/// use cosmwasm_std::{Response, StdResult};
607/// use provwasm_std::{mint_marker_supply, ProvenanceMsg};
608///
609/// // Create and dispatch a message that will mint marker supply.
610/// fn try_mint_marker(amount: u128, denom: String) -> StdResult<Response<ProvenanceMsg>> {
611/// let msg = mint_marker_supply(amount, &denom)?;
612/// let mut res = Response::new().add_message(msg);
613/// Ok(res)
614/// }
615/// ```
616pub fn mint_marker_supply<S: Into<String>>(
617 amount: u128,
618 denom: S,
619) -> StdResult<CosmosMsg<ProvenanceMsg>> {
620 if amount == 0 {
621 return Err(StdError::generic_err("mint amount must be > 0"));
622 }
623 let coin = coin(amount, validate_string(denom, "denom")?);
624 Ok(create_marker_msg(MarkerMsgParams::MintMarkerSupply {
625 coin,
626 }))
627}
628
629/// Create a message that will burn marker coins.
630///
631/// ### Example
632///
633/// ```rust
634/// // Imports required
635/// use cosmwasm_std::{Response, StdResult};
636/// use provwasm_std::{burn_marker_supply, ProvenanceMsg};
637///
638/// // Create and dispatch a message that will burn marker supply.
639/// fn try_burn_marker(amount: u128, denom: String) -> StdResult<Response<ProvenanceMsg>> {
640/// let msg = burn_marker_supply(amount, &denom)?;
641/// let mut res = Response::new().add_message(msg);
642/// Ok(res)
643/// }
644/// ```
645pub fn burn_marker_supply<S: Into<String>>(
646 amount: u128,
647 denom: S,
648) -> StdResult<CosmosMsg<ProvenanceMsg>> {
649 if amount == 0 {
650 return Err(StdError::generic_err("burn amount must be > 0"));
651 }
652 let coin = coin(amount, validate_string(denom, "denom")?);
653 Ok(create_marker_msg(MarkerMsgParams::BurnMarkerSupply {
654 coin,
655 }))
656}
657
658/// Create a message that will withdraw coins from a marker account to a recipient account.
659///
660/// ### Example
661///
662/// ```rust
663/// // Imports required
664/// use cosmwasm_std::{Addr, Response, StdResult};
665/// use provwasm_std::{withdraw_coins, ProvenanceMsg};
666///
667/// // Create and dispatch a message that will withdraw coins from a marker.
668/// fn try_withdraw_coins(
669/// marker_denom: String,
670/// amount: u128,
671/// denom: String,
672/// recipient: Addr,
673/// ) -> StdResult<Response<ProvenanceMsg>> {
674/// let msg = withdraw_coins(&marker_denom, amount, &denom, recipient)?;
675/// let mut res = Response::new().add_message(msg);
676/// Ok(res)
677/// }
678/// ```
679pub fn withdraw_coins<S: Into<String>, H: Into<Addr>>(
680 marker_denom: S,
681 amount: u128,
682 denom: S,
683 recipient: H,
684) -> StdResult<CosmosMsg<ProvenanceMsg>> {
685 if amount == 0 {
686 return Err(StdError::generic_err("withdraw amount must be > 0"));
687 }
688 let coin = coin(amount, validate_string(denom, "denom")?);
689 Ok(create_marker_msg(MarkerMsgParams::WithdrawCoins {
690 marker_denom: validate_string(marker_denom, "marker_denom")?,
691 coin,
692 recipient: validate_address(recipient)?,
693 }))
694}
695
696/// Create a message that will transfer a marker amount from one account to another.
697///
698/// ### Example
699///
700/// ```rust
701/// // Imports required
702/// use cosmwasm_std::{Addr, Response, StdResult};
703/// use provwasm_std::{transfer_marker_coins, ProvenanceMsg};
704///
705/// // Create and dispatch a message that will transfer marker coins from one account to another.
706/// // NOTE: Transfer is only enabled for restricted markers.
707/// fn try_transfer_marker_coins(
708/// amount: u128,
709/// denom: String,
710/// to: Addr,
711/// from: Addr,
712/// ) -> StdResult<Response<ProvenanceMsg>> {
713/// let msg = transfer_marker_coins(amount, &denom, to, from)?;
714/// let mut res = Response::new().add_message(msg);
715/// Ok(res)
716/// }
717/// ```
718pub fn transfer_marker_coins<S: Into<String>, H: Into<Addr>>(
719 amount: u128,
720 denom: S,
721 to: H,
722 from: H,
723) -> StdResult<CosmosMsg<ProvenanceMsg>> {
724 if amount == 0 {
725 return Err(StdError::generic_err("transfer amount must be > 0"));
726 }
727 let coin = coin(amount, validate_string(denom, "denom")?);
728 let msg = create_marker_msg(MarkerMsgParams::TransferMarkerCoins {
729 coin,
730 to: validate_address(to)?,
731 from: validate_address(from)?,
732 });
733 Ok(msg)
734}
735
736/// Input params for creating marker module messages.
737#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, JsonSchema)]
738#[serde(rename_all = "snake_case")]
739pub enum MetadataMsgParams {
740 WriteScope { scope: Scope, signers: Vec<Addr> },
741}
742
743// Create a custom cosmos message using metadata module params.
744fn create_metadata_msg(params: MetadataMsgParams) -> CosmosMsg<ProvenanceMsg> {
745 CosmosMsg::Custom(ProvenanceMsg {
746 route: ProvenanceRoute::Metadata,
747 params: ProvenanceMsgParams::Metadata(params),
748 version: String::from(MSG_DATAFMT_VERSION),
749 })
750}
751
752/// Create a message that will create, or update, a scope.
753///
754/// ### Example
755///
756/// ```rust
757/// // Imports required
758/// use cosmwasm_std::{Addr, Response, StdError};
759/// use provwasm_std::{ProvenanceMsg, Scope, write_scope};
760///
761/// // Create and dispatch a message that will create, or update, a scope.
762/// fn try_write_scope(scope: Scope, signers: Vec<Addr>) -> Result<Response<ProvenanceMsg>, StdError> {
763/// let msg = write_scope(scope, signers)?;
764/// let mut res = Response::new().add_message(msg);
765/// Ok(res)
766/// }
767/// ```
768pub fn write_scope<S: Into<Scope>, H: Into<Addr>>(
769 scope: S,
770 signers: Vec<H>,
771) -> Result<CosmosMsg<ProvenanceMsg>, StdError> {
772 Ok(create_metadata_msg(MetadataMsgParams::WriteScope {
773 scope: scope.into(),
774 signers: signers
775 .into_iter()
776 .map(validate_address)
777 .collect::<Result<Vec<Addr>, _>>()?,
778 }))
779}
780
781/// Input params for creating msgfee module messages.
782#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, JsonSchema)]
783#[serde(rename_all = "snake_case")]
784pub enum MsgFeesMsgParams {
785 AssessCustomFee {
786 amount: Coin,
787 from: Addr,
788 name: Option<String>,
789 recipient: Option<Addr>,
790 },
791}
792
793// Create a custom cosmos message using msgfees module params.
794fn create_msgfees_msg(params: MsgFeesMsgParams) -> CosmosMsg<ProvenanceMsg> {
795 CosmosMsg::Custom(ProvenanceMsg {
796 route: ProvenanceRoute::Msgfees,
797 params: ProvenanceMsgParams::MsgFees(params),
798 version: String::from(MSG_DATAFMT_VERSION),
799 })
800}
801
802/// Create a message that will assess a custom fee
803/// ### Example
804///
805/// ```rust
806/// use cosmwasm_std::{Addr, Coin, Response, StdError};
807/// use provwasm_std::{assess_custom_fee, MsgFeesMsgParams, ProvenanceMsg};
808///
809/// fn try_assess_custom_fee(amount: Coin, name: Option<String>, from: Addr, recipient: Option<Addr>) -> Result<Response<ProvenanceMsg>, StdError>{
810/// let msg = assess_custom_fee(amount, name, from, recipient)?;
811/// let res = Response::new().add_message(msg);
812/// Ok(res)
813/// }
814/// ```
815pub fn assess_custom_fee<S: Into<String>>(
816 amount: Coin,
817 name: Option<S>,
818 from: Addr,
819 recipient: Option<Addr>,
820) -> Result<CosmosMsg<ProvenanceMsg>, StdError> {
821 Ok(create_msgfees_msg(MsgFeesMsgParams::AssessCustomFee {
822 amount,
823 name: name.map(|name| name.into()),
824 from,
825 recipient,
826 }))
827}