Skip to content

Commit

Permalink
add: more csl.rs helpers (#405)
Browse files Browse the repository at this point in the history
  • Loading branch information
AmbientTea authored Jan 21, 2025
1 parent 7bbd0cf commit 6d654e9
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 31 deletions.
51 changes: 47 additions & 4 deletions toolkit/offchain/src/csl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -406,10 +406,7 @@ impl TransactionBuilderExt for TransactionBuilder {
.with_address(&validator.address(ctx.network))
.with_plutus_data(datum)
.next()?;
let mut ma = MultiAsset::new();
let mut assets = Assets::new();
assets.insert(&empty_asset_name(), &1u64.into());
ma.insert(&policy.script_hash().into(), &assets);
let ma = MultiAsset::new().with_asset_amount(&policy.empty_name_asset(), 1u64)?;
let output = amount_builder.with_coin_and_asset(&0u64.into(), &ma).build()?;
let min_ada = MinOutputAdaCalculator::new(
&output,
Expand Down Expand Up @@ -674,6 +671,52 @@ impl AssetNameExt for sidechain_domain::AssetName {
}
}

pub(crate) trait AssetIdExt {
fn to_multi_asset(&self, amount: impl Into<BigNum>) -> Result<MultiAsset, JsError>;
}
impl AssetIdExt for AssetId {
fn to_multi_asset(&self, amount: impl Into<BigNum>) -> Result<MultiAsset, JsError> {
let mut ma = MultiAsset::new();
let mut assets = Assets::new();
assets.insert(&self.asset_name.to_csl()?, &amount.into());
ma.insert(&self.policy_id.0.into(), &assets);
Ok(ma)
}
}
pub(crate) trait MultiAssetExt: Sized {
fn from_ogmios_utxo(utxo: &OgmiosUtxo) -> Result<Self, JsError>;
fn with_asset_amount(self, asset: &AssetId, amount: impl Into<BigNum>)
-> Result<Self, JsError>;
}

impl MultiAssetExt for MultiAsset {
fn from_ogmios_utxo(utxo: &OgmiosUtxo) -> Result<Self, JsError> {
let mut ma = MultiAsset::new();
for (policy, policy_assets) in utxo.value.native_tokens.iter() {
let mut assets = Assets::new();
for asset in policy_assets {
assets.insert(
&cardano_serialization_lib::AssetName::new(asset.name.clone())?,
&(asset.amount as u64).into(),
);
}
ma.insert(&PolicyID::from(*policy), &assets);
}
Ok(ma)
}
fn with_asset_amount(
mut self,
asset: &AssetId,
amount: impl Into<BigNum>,
) -> Result<Self, JsError> {
self.set_asset(&asset.policy_id.0.into(), &asset.asset_name.to_csl()?, &0u64.into());
let mut assets = Assets::new();
assets.insert(&asset.asset_name.to_csl()?, &amount.into());
self.insert(&asset.policy_id.0.into(), &assets);
Ok(self)
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
34 changes: 33 additions & 1 deletion toolkit/offchain/src/plutus_script.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use cardano_serialization_lib::{
};
use ogmios_client::types::{OgmiosScript, OgmiosScript::Plutus};
use plutus::ToDatum;
use sidechain_domain::PolicyId;
use sidechain_domain::{AssetId, AssetName, PolicyId};
use uplc::ast::{DeBruijn, Program};

use crate::{csl::*, untyped_plutus::*};
Expand Down Expand Up @@ -102,6 +102,10 @@ impl PlutusScript {
PolicyId(self.script_hash())
}

pub fn empty_name_asset(&self) -> AssetId {
AssetId { policy_id: self.policy_id(), asset_name: AssetName::empty() }
}

pub fn to_csl(&self) -> cardano_serialization_lib::PlutusScript {
match self.language.kind() {
LanguageKind::PlutusV1 => {
Expand All @@ -117,6 +121,34 @@ impl PlutusScript {
}
}

impl TryFrom<ogmios_client::types::PlutusScript> for PlutusScript {
type Error = ogmios_client::types::PlutusScript;

fn try_from(script: ogmios_client::types::PlutusScript) -> Result<Self, Self::Error> {
let language = match script.language.as_str() {
"plutus:v1" => Language::new_plutus_v1(),
"plutus:v2" => Language::new_plutus_v2(),
"plutus:v3" => Language::new_plutus_v3(),
_ => return Err(script),
};
Ok(Self::from_cbor(&script.cbor, language))
}
}

impl Into<ogmios_client::types::PlutusScript> for PlutusScript {
fn into(self) -> ogmios_client::types::PlutusScript {
ogmios_client::types::PlutusScript {
language: match self.language.kind() {
LanguageKind::PlutusV1 => "plutus:v1",
LanguageKind::PlutusV2 => "plutus:v2",
LanguageKind::PlutusV3 => "plutus:v3",
}
.to_string(),
cbor: self.bytes,
}
}
}

#[cfg(test)]
pub(crate) mod tests {
use super::*;
Expand Down
17 changes: 4 additions & 13 deletions toolkit/offchain/src/reserve/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use crate::{
await_tx::AwaitTx,
csl::{
empty_asset_name, get_builder_config, get_validator_budgets, zero_ex_units, AssetNameExt,
OgmiosUtxoExt, TransactionBuilderExt, TransactionContext,
MultiAssetExt, OgmiosUtxoExt, TransactionBuilderExt, TransactionContext,
TransactionOutputAmountBuilderExt,
},
init_governance::{get_governance_data, GovernanceData},
Expand Down Expand Up @@ -192,18 +192,9 @@ fn reserve_validator_output(
.with_address(&scripts.validator.address(ctx.network))
.with_plutus_data(&ReserveDatum::from(parameters).into())
.next()?;
let mut ma = MultiAsset::new();
let mut assets = Assets::new();
assets.insert(&empty_asset_name(), &1u64.into());
ma.insert(&scripts.auth_policy.csl_script_hash(), &assets);

let AssetId { policy_id, asset_name } = parameters.token.clone();
let mut assets = Assets::new();
assets.insert(
&asset_name.to_csl().expect("AssetName has a valid length"),
&parameters.initial_deposit.into(),
);
ma.insert(&policy_id.0.into(), &assets);
let ma = MultiAsset::new()
.with_asset_amount(&scripts.auth_policy.empty_name_asset(), 1u64)?
.with_asset_amount(&parameters.token, parameters.initial_deposit)?;

amount_builder.with_minimum_ada_and_asset(&ma, ctx)?.build()
}
18 changes: 5 additions & 13 deletions toolkit/offchain/src/reserve/deposit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ use super::{ReserveData, TokenAmount};
use crate::{
await_tx::AwaitTx,
csl::{
empty_asset_name, get_builder_config, get_validator_budgets, zero_ex_units, OgmiosUtxoExt,
OgmiosValueExt, TransactionBuilderExt, TransactionContext,
empty_asset_name, get_builder_config, get_validator_budgets, zero_ex_units, MultiAssetExt,
OgmiosUtxoExt, OgmiosValueExt, TransactionBuilderExt, TransactionContext,
TransactionOutputAmountBuilderExt,
},
init_governance::{get_governance_data, GovernanceData},
Expand Down Expand Up @@ -242,17 +242,9 @@ fn validator_output(
.unwrap(),
)
.next()?;
let mut ma = MultiAsset::new();
let mut assets = Assets::new();
assets.insert(&empty_asset_name(), &1u64.into());
ma.insert(&scripts.auth_policy.csl_script_hash(), &assets);
let AssetId { policy_id, asset_name } = token_amount.token.clone();
let mut assets = Assets::new();
assets.insert(
&AssetName::new(asset_name.0.to_vec()).expect("AssetName has a valid length"),
&token_amount.amount.into(),
);
ma.insert(&policy_id.0.into(), &assets);
let ma = MultiAsset::new()
.with_asset_amount(&token_amount.token, token_amount.amount)?
.with_asset_amount(&scripts.auth_policy.empty_name_asset(), 1u64)?;

amount_builder.with_minimum_ada_and_asset(&ma, ctx)?.build()
}
12 changes: 12 additions & 0 deletions toolkit/primitives/domain/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,12 @@ const MAX_MAINCHAIN_ADDRESS_BYTES: u32 = 120;
#[cfg_attr(feature = "serde", byte_string(hex_serialize, hex_deserialize))]
pub struct MainchainAddress(BoundedVec<u8, ConstU32<MAX_MAINCHAIN_ADDRESS_BYTES>>);

impl MainchainAddress {
pub fn bytes(&self) -> Vec<u8> {
self.0.to_vec()
}
}

#[cfg(feature = "serde")]
impl FromStr for MainchainAddress {
type Err = &'static str;
Expand Down Expand Up @@ -206,6 +212,12 @@ pub const MAX_ASSET_NAME_LEN: u32 = 32;
#[byte_string(debug, hex_serialize, hex_deserialize, decode_hex)]
pub struct AssetName(pub BoundedVec<u8, ConstU32<MAX_ASSET_NAME_LEN>>);

impl AssetName {
pub fn empty() -> Self {
Self(BoundedVec::new())
}
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct AssetId {
pub policy_id: PolicyId,
Expand Down

0 comments on commit 6d654e9

Please sign in to comment.