#![allow(clippy::field_reassign_with_default)]
use cosmwasm_std::{to_binary, Binary, Coin, CosmosMsg, HumanAddr, StdResult};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use crate::types::{AttributeValueType, MarkerAccess, MarkerType, ProvenanceRoute};
static MSG_DATAFMT_VERSION: &str = "2.0.0";
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub struct ProvenanceMsg {
pub route: ProvenanceRoute,
pub params: ProvenanceMsgParams,
pub version: String,
}
impl From<ProvenanceMsg> for CosmosMsg<ProvenanceMsg> {
fn from(msg: ProvenanceMsg) -> CosmosMsg<ProvenanceMsg> {
CosmosMsg::Custom(msg)
}
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub enum ProvenanceMsgParams {
Name(NameMsgParams),
Attribute(AttributeMsgParams),
Marker(MarkerMsgParams),
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum NameMsgParams {
BindName {
name: String,
address: HumanAddr,
restrict: bool,
},
DeleteName {
name: String,
},
}
impl From<NameMsgParams> for ProvenanceMsgParams {
fn from(params: NameMsgParams) -> ProvenanceMsgParams {
ProvenanceMsgParams::Name(params)
}
}
fn create_name_msg(params: NameMsgParams) -> CosmosMsg<ProvenanceMsg> {
ProvenanceMsg {
route: ProvenanceRoute::Name,
params: params.into(),
version: String::from(MSG_DATAFMT_VERSION),
}
.into()
}
pub fn bind_name(name: String, address: HumanAddr) -> CosmosMsg<ProvenanceMsg> {
create_name_msg(NameMsgParams::BindName {
name,
address,
restrict: true,
})
}
pub fn bind_name_unrestricted(name: String, address: HumanAddr) -> CosmosMsg<ProvenanceMsg> {
create_name_msg(NameMsgParams::BindName {
name,
address,
restrict: false,
})
}
pub fn unbind_name(name: String) -> CosmosMsg<ProvenanceMsg> {
create_name_msg(NameMsgParams::DeleteName { name })
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum AttributeMsgParams {
AddAttribute {
address: HumanAddr,
name: String,
value: Binary,
value_type: AttributeValueType,
},
DeleteAttribute {
name: String,
address: HumanAddr,
},
}
impl From<AttributeMsgParams> for ProvenanceMsgParams {
fn from(params: AttributeMsgParams) -> ProvenanceMsgParams {
ProvenanceMsgParams::Attribute(params)
}
}
fn create_attribute_msg(params: AttributeMsgParams) -> CosmosMsg<ProvenanceMsg> {
ProvenanceMsg {
route: ProvenanceRoute::Attribute,
params: params.into(),
version: String::from(MSG_DATAFMT_VERSION),
}
.into()
}
pub fn add_attribute(
address: HumanAddr,
name: String,
value: Binary,
value_type: AttributeValueType,
) -> CosmosMsg<ProvenanceMsg> {
create_attribute_msg(AttributeMsgParams::AddAttribute {
address,
name,
value,
value_type,
})
}
pub fn add_uuid_attribute(
address: HumanAddr,
name: String,
uuid: String,
) -> CosmosMsg<ProvenanceMsg> {
add_attribute(
address,
name,
Binary::from(uuid.as_bytes()),
AttributeValueType::Uuid,
)
}
pub fn add_binary_attribute(
address: HumanAddr,
name: String,
value: Binary,
) -> CosmosMsg<ProvenanceMsg> {
add_attribute(address, name, value, AttributeValueType::Bytes)
}
pub fn add_string_attribute(
address: HumanAddr,
name: String,
value: String,
) -> CosmosMsg<ProvenanceMsg> {
add_attribute(
address,
name,
Binary::from(value.as_bytes()),
AttributeValueType::String,
)
}
pub fn add_json_attribute<T: Serialize + ?Sized>(
address: HumanAddr,
name: String,
data: &T,
) -> StdResult<CosmosMsg<ProvenanceMsg>> {
let value = to_binary(data)?;
Ok(add_attribute(
address,
name,
value,
AttributeValueType::Json,
))
}
pub fn delete_attributes(name: String, address: HumanAddr) -> CosmosMsg<ProvenanceMsg> {
create_attribute_msg(AttributeMsgParams::DeleteAttribute { name, address })
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum MarkerMsgParams {
CreateMarker {
coin: Coin,
marker_type: MarkerType,
},
GrantMarkerAccess {
denom: String,
address: HumanAddr,
permissions: Vec<MarkerAccess>,
},
RevokeMarkerAccess {
denom: String,
address: HumanAddr,
},
FinalizeMarker {
denom: String,
},
ActivateMarker {
denom: String,
},
CancelMarker {
denom: String,
},
DestroyMarker {
denom: String,
},
MintMarkerSupply {
coin: Coin,
},
BurnMarkerSupply {
coin: Coin,
},
WithdrawMarkerCoins {
coin: Coin,
recipient: HumanAddr,
},
TransferMarkerCoins {
coin: Coin,
to: HumanAddr,
from: HumanAddr,
},
}
impl From<MarkerMsgParams> for ProvenanceMsgParams {
fn from(params: MarkerMsgParams) -> ProvenanceMsgParams {
ProvenanceMsgParams::Marker(params)
}
}
fn create_marker_msg(params: MarkerMsgParams) -> CosmosMsg<ProvenanceMsg> {
ProvenanceMsg {
route: ProvenanceRoute::Marker,
params: params.into(),
version: String::from(MSG_DATAFMT_VERSION),
}
.into()
}
pub fn create_marker(coin: Coin) -> CosmosMsg<ProvenanceMsg> {
create_marker_with_type(coin, MarkerType::Coin)
}
pub fn create_restricted_marker(coin: Coin) -> CosmosMsg<ProvenanceMsg> {
create_marker_with_type(coin, MarkerType::Restricted)
}
fn create_marker_with_type(coin: Coin, marker_type: MarkerType) -> CosmosMsg<ProvenanceMsg> {
create_marker_msg(MarkerMsgParams::CreateMarker { coin, marker_type })
}
pub fn grant_marker_access(
denom: String,
address: HumanAddr,
permissions: Vec<MarkerAccess>,
) -> CosmosMsg<ProvenanceMsg> {
create_marker_msg(MarkerMsgParams::GrantMarkerAccess {
denom,
address,
permissions,
})
}
pub fn grant_marker_access_all(denom: String, address: HumanAddr) -> CosmosMsg<ProvenanceMsg> {
grant_marker_access(
denom,
address,
vec![
MarkerAccess::Admin,
MarkerAccess::Burn,
MarkerAccess::Delete,
MarkerAccess::Deposit,
MarkerAccess::Mint,
MarkerAccess::Transfer,
MarkerAccess::Withdraw,
],
)
}
pub fn grant_marker_access_supply(denom: String, address: HumanAddr) -> CosmosMsg<ProvenanceMsg> {
grant_marker_access(denom, address, vec![MarkerAccess::Burn, MarkerAccess::Mint])
}
pub fn grant_marker_access_asset(denom: String, address: HumanAddr) -> CosmosMsg<ProvenanceMsg> {
grant_marker_access(
denom,
address,
vec![MarkerAccess::Deposit, MarkerAccess::Withdraw],
)
}
pub fn revoke_marker_access(denom: String, address: HumanAddr) -> CosmosMsg<ProvenanceMsg> {
create_marker_msg(MarkerMsgParams::RevokeMarkerAccess { denom, address })
}
pub fn finalize_marker(denom: String) -> CosmosMsg<ProvenanceMsg> {
create_marker_msg(MarkerMsgParams::FinalizeMarker { denom })
}
pub fn activate_marker(denom: String) -> CosmosMsg<ProvenanceMsg> {
create_marker_msg(MarkerMsgParams::ActivateMarker { denom })
}
pub fn cancel_marker(denom: String) -> CosmosMsg<ProvenanceMsg> {
create_marker_msg(MarkerMsgParams::CancelMarker { denom })
}
pub fn destroy_marker(denom: String) -> CosmosMsg<ProvenanceMsg> {
create_marker_msg(MarkerMsgParams::DestroyMarker { denom })
}
pub fn mint_marker_supply(coin: Coin) -> CosmosMsg<ProvenanceMsg> {
create_marker_msg(MarkerMsgParams::MintMarkerSupply { coin })
}
pub fn burn_marker_supply(coin: Coin) -> CosmosMsg<ProvenanceMsg> {
create_marker_msg(MarkerMsgParams::BurnMarkerSupply { coin })
}
pub fn withdraw_marker_coins(coin: Coin, recipient: HumanAddr) -> CosmosMsg<ProvenanceMsg> {
create_marker_msg(MarkerMsgParams::WithdrawMarkerCoins { coin, recipient })
}
pub fn transfer_marker_coins(
coin: Coin,
to: HumanAddr,
from: HumanAddr,
) -> CosmosMsg<ProvenanceMsg> {
create_marker_msg(MarkerMsgParams::TransferMarkerCoins { coin, to, from })
}