Skip to content

Commit

Permalink
feat: building plutus types
Browse files Browse the repository at this point in the history
  • Loading branch information
HinsonSIDAN committed Jan 22, 2024
1 parent 6aa718b commit 736e8c7
Show file tree
Hide file tree
Showing 12 changed files with 268 additions and 22 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "sidan-csl-rs"
version = "0.1.7"
version = "0.1.8"
edition = "2021"
license = "MIT"
description = "Wrapper around the cardano-serialization-lib for easier transaction building, heavily inspired by cardano-cli APIs"
Expand Down
2 changes: 1 addition & 1 deletion src/builder/core.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use cardano_serialization_lib as csl;

use crate::{
builder::models::*,
model::builder::*,
utils::csl::{build_tx_builder, to_bignum, to_value},
};

Expand Down
1 change: 0 additions & 1 deletion src/builder/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
pub mod core;
pub mod models;
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pub mod builder;
pub mod model;
pub mod utils;
File renamed without changes.
1 change: 1 addition & 0 deletions src/model/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod builder;
11 changes: 10 additions & 1 deletion src/utils/csl.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use cardano_serialization_lib as csl;

use crate::builder::models::*;
use crate::model::builder::*;
use hex::FromHex;

pub fn to_bignum(val: u64) -> csl::utils::BigNum {
Expand Down Expand Up @@ -154,3 +154,12 @@ pub fn get_v2_script_hash(script: &str) -> String {
.hash()
.to_hex()
}

pub fn address_bech32_to_obj(bech32: &str) {}

// export const addrBech32ToObj = <T>(bech32: string): T => {
// const hexAddress = csl.Address.from_bech32(bech32).to_hex();
// const cslAddress = csl.Address.from_hex(hexAddress);
// const json = JSON.parse(csl.PlutusData.from_address(cslAddress).to_json(1));
// return json;
// };
1 change: 1 addition & 0 deletions src/utils/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod aiken;
pub mod csl;
pub mod parser;
pub mod plutus_types;
240 changes: 240 additions & 0 deletions src/utils/plutus_types.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
use serde_json::{json, Value};

pub fn con_str<N: Into<Value>, T: Into<Value>>(constructor: N, fields: T) -> Value {
json!({ "constructor": constructor.into(), "fields": fields.into() })
}

pub fn con_str0<T: Into<Value>>(fields: T) -> Value {
con_str(0, fields)
}

pub fn con_str1<T: Into<Value>>(fields: T) -> Value {
con_str(1, fields)
}

pub fn con_str2<T: Into<Value>>(fields: T) -> Value {
con_str(2, fields)
}

pub fn bool(b: bool) -> Value {
if b {
con_str1(json!([]))
} else {
con_str0(json!([]))
}
}

pub fn builtin_byte_string(bytes: &str) -> Value {
json!({ "bytes": bytes })
}

pub fn integer(int: i32) -> Value {
json!({ "int": int })
}

pub fn list<T: Into<Value>>(p_list: Vec<T>) -> Value {
let list: Vec<Value> = p_list.into_iter().map(|item| item.into()).collect();
json!({ "list": list })
}

// Other functions like currencySymbol, tokenName, etc., would create JSON objects
pub fn currency_symbol(policy_id: &str) -> Value {
builtin_byte_string(policy_id)
}

pub fn token_name(token_name: &str) -> Value {
builtin_byte_string(token_name)
}

pub fn maybe_staking_hash(stake_credential: &str) -> Value {
if stake_credential.is_empty() {
con_str1(json!([]))
} else {
con_str0(vec![con_str0(vec![con_str0(vec![builtin_byte_string(
stake_credential,
)])])])
}
}

pub fn pub_key_address(bytes: &str, stake_credential: Option<&str>) -> Value {
con_str0(vec![
con_str0(vec![builtin_byte_string(bytes)]),
maybe_staking_hash(stake_credential.unwrap_or("")),
])
}

pub fn script_address(bytes: &str, stake_credential: Option<&str>) -> Value {
con_str0(vec![
con_str1(vec![builtin_byte_string(bytes)]),
maybe_staking_hash(stake_credential.unwrap_or("")),
])
}

pub fn asset_class(policy_id: &str, asset_name: &str) -> Value {
con_str0(vec![currency_symbol(policy_id), token_name(asset_name)])
}

pub fn tx_out_ref(tx_hash: &str, index: i32) -> Value {
con_str0(vec![
con_str0(vec![builtin_byte_string(tx_hash)]),
integer(index),
])
}

pub fn assoc_map<K: Into<Value>, V: Into<Value>>(items_map: Vec<(K, V)>) -> Value {
let map: Vec<Value> = items_map
.into_iter()
.map(|(k, v)| json!({"k": k.into(), "v": v.into()}))
.collect();
json!({ "map": map })
}

pub fn tuple<K: Into<Value>, V: Into<Value>>(key: K, value: V) -> Value {
con_str0(vec![key.into(), value.into()])
}

pub fn payment_pub_key_hash(pub_key_hash: &str) -> Value {
builtin_byte_string(pub_key_hash)
}

pub fn pub_key_hash(pub_key_hash: &str) -> Value {
builtin_byte_string(pub_key_hash)
}

pub fn posix_time(posix_time: i32) -> Value {
integer(posix_time)
}

#[test]
fn test_con_str() {
let correct_con_str = "{\"constructor\":10,\"fields\":[{\"bytes\":\"hello\"}]}";
assert_eq!(
con_str(10, json!([builtin_byte_string("hello")])).to_string(),
correct_con_str
);
}

#[test]
fn test_con_str0() {
let correct_con_str0 = "{\"constructor\":0,\"fields\":{\"bytes\":\"hello\"}}";
assert_eq!(
con_str0(builtin_byte_string("hello")).to_string(),
correct_con_str0
);
}

#[test]
fn test_con_str1() {
let correct_con_str1 = "{\"constructor\":1,\"fields\":{\"bytes\":\"hello\"}}";
assert_eq!(
con_str1(builtin_byte_string("hello")).to_string(),
correct_con_str1
);
}

#[test]
fn test_con_str2() {
let correct_con_str2 = "{\"constructor\":2,\"fields\":{\"bytes\":\"hello\"}}";
assert_eq!(
con_str2(builtin_byte_string("hello")).to_string(),
correct_con_str2
);
}

#[test]
fn test_bool() {
let correct_bool = "{\"constructor\":1,\"fields\":[]}";
assert_eq!(bool(true).to_string(), correct_bool);
}

#[test]
fn test_builtin_byte_string() {
let correct_builtin_byte_string = "{\"bytes\":\"hello\"}";
assert_eq!(
builtin_byte_string("hello").to_string(),
correct_builtin_byte_string
);
}

#[test]
fn test_integer() {
let correct_integer = "{\"int\":1}";
assert_eq!(integer(1).to_string(), correct_integer);
}

#[test]
fn test_list() {
let correct_list = "{\"list\":[1,2,3]}";
assert_eq!(list(vec![1, 2, 3]).to_string(), correct_list);
}

#[test]
fn test_maybe_staking_hash() {
let correct_maybe_staking_hash = "{\"constructor\":0,\"fields\":[{\"constructor\":0,\"fields\":[{\"constructor\":0,\"fields\":[{\"bytes\":\"hello\"}]}]}]}";
assert_eq!(
maybe_staking_hash("hello").to_string(),
correct_maybe_staking_hash
);
}

#[test]
fn test_pub_key_address() {
let correct_pub_key_address = "{\"constructor\":0,\"fields\":[{\"constructor\":0,\"fields\":[{\"bytes\":\"8f2ac4b2a57a90feb7717c7361c7043af6c3646e9db2b0e616482f73\"}]},{\"constructor\":0,\"fields\":[{\"constructor\":0,\"fields\":[{\"constructor\":0,\"fields\":[{\"bytes\":\"039506b8e57e150bb66f6134f3264d50c3b70ce44d052f4485cf388f\"}]}]}]}]}";
assert_eq!(
pub_key_address(
"8f2ac4b2a57a90feb7717c7361c7043af6c3646e9db2b0e616482f73",
Some("039506b8e57e150bb66f6134f3264d50c3b70ce44d052f4485cf388f")
)
.to_string(),
correct_pub_key_address
);
}

#[test]
fn test_script_address() {
let correct_script_address = "{\"constructor\":0,\"fields\":[{\"constructor\":1,\"fields\":[{\"bytes\":\"hello\"}]},{\"constructor\":1,\"fields\":[]}]}";
assert_eq!(
script_address("hello", None).to_string(),
correct_script_address
);
}

#[test]
fn test_asset_class() {
let correct_asset_class =
"{\"constructor\":0,\"fields\":[{\"bytes\":\"hello\"},{\"bytes\":\"world\"}]}";
assert_eq!(
asset_class("hello", "world").to_string(),
correct_asset_class
);
}

#[test]
fn test_tx_out_ref() {
let correct_tx_out_ref = "{\"constructor\":0,\"fields\":[{\"constructor\":0,\"fields\":[{\"bytes\":\"hello\"}]},{\"int\":12}]}";
assert_eq!(tx_out_ref("hello", 12).to_string(), correct_tx_out_ref);
}

#[test]
fn test_assoc_map() {
let correct_assoc_map =
"{\"map\":[{\"k\":{\"bytes\":\"hello\"},\"v\":{\"bytes\":\"world\"}},{\"k\":{\"bytes\":\"123\"},\"v\":{\"bytes\":\"456\"}}]}";
assert_eq!(
assoc_map(vec![
(builtin_byte_string("hello"), builtin_byte_string("world")),
(builtin_byte_string("123"), builtin_byte_string("456"))
])
.to_string(),
correct_assoc_map
);
}

#[test]
fn test_tuple() {
let correct_tuple =
"{\"constructor\":0,\"fields\":[{\"bytes\":\"hello\"},{\"bytes\":\"world\"}]}";
assert_eq!(
tuple(builtin_byte_string("hello"), builtin_byte_string("world")).to_string(),
correct_tuple
);
}
12 changes: 6 additions & 6 deletions tests/integration_tests.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
mod int_tests {
use serde_json::{json, to_string};
use sidan_csl_rs::builder::{
core::MeshTxBuilderCore,
models::{Asset, Budget, Redeemer},
use sidan_csl_rs::{
builder::core::MeshTxBuilderCore,
model::builder::{Asset, Budget, LanguageVersion, Redeemer},
};

#[test]
Expand Down Expand Up @@ -65,7 +65,7 @@ mod int_tests {
cns_token_mp_script_ref_txhash.to_string(),
cns_token_mp_script_ref_txid.parse::<u32>().unwrap(),
cns_policy_id.to_string(),
sidan_csl_rs::builder::models::LanguageVersion::V2,
LanguageVersion::V2,
)
.mint_redeemer_value(Redeemer {
data: to_string(&json!({
Expand Down Expand Up @@ -104,7 +104,7 @@ mod int_tests {
record_validator_script_ref_txhash.to_string(),
record_validator_script_ref_txid.parse::<u32>().unwrap(),
"8be60057c65fbae6d5c0673f899fea68868b16aeba6ff06f2d7f3161".to_string(),
sidan_csl_rs::builder::models::LanguageVersion::V2,
LanguageVersion::V2,
)
.tx_out(
wallet_address.to_string(),
Expand Down Expand Up @@ -169,6 +169,6 @@ mod int_tests {
.change_address(wallet_address.to_string())
.complete_sync(None);

assert!(mesh.tx_hex != "".to_string());
assert!(mesh.tx_hex != *"");
}
}
17 changes: 6 additions & 11 deletions tests/unit_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@ mod tests {
use serde_json::{json, to_string};
use sidan_csl_rs::utils::csl::script_to_address;
use sidan_csl_rs::{
builder::{
core::MeshTxBuilderCore,
models::{Asset, Budget, Redeemer, SerializedAddress},
},
builder::core::MeshTxBuilderCore,
model::builder::{Asset, Budget, LanguageVersion, Redeemer, SerializedAddress},
utils::csl::{get_v2_script_hash, serialize_bech32_address},
};

Expand Down Expand Up @@ -116,7 +114,7 @@ mod tests {
"bb712547a5abe3697f8aba72870e33a52fd2c0401715950197f9b7370d137998".to_string(),
0,
"8be60057c65fbae6d5c0673f899fea68868b16aeba6ff06f2d7f3161".to_string(),
sidan_csl_rs::builder::models::LanguageVersion::V2,
LanguageVersion::V2,
)
.tx_in_datum_value(data.clone())
.spending_reference_tx_in_redeemer_value(Redeemer {
Expand Down Expand Up @@ -150,10 +148,7 @@ mod tests {
vec![asset],
"addr_test1vr3vljjxan0hl6u28fle2l4ds6ugc9t08lwevpauk38t3agx7rtq6".to_string(),
)
.tx_in_script(
script_cbor,
sidan_csl_rs::builder::models::LanguageVersion::V2,
)
.tx_in_script(script_cbor, LanguageVersion::V2)
.tx_in_datum_value(data.clone())
.spending_reference_tx_in_redeemer_value(Redeemer {
data: data.clone(),
Expand Down Expand Up @@ -189,7 +184,7 @@ mod tests {
"bb712547a5abe3697f8aba72870e33a52fd2c0401715950197f9b7370d137998".to_string(),
0,
"8be60057c65fbae6d5c0673f899fea68868b16aeba6ff06f2d7f3161".to_string(),
sidan_csl_rs::builder::models::LanguageVersion::V2,
LanguageVersion::V2,
)
.tx_in_datum_value(data.clone())
.spending_reference_tx_in_redeemer_value(Redeemer {
Expand Down Expand Up @@ -227,7 +222,7 @@ mod tests {
"63210437b543c8a11afbbc6765aa205eb2733cb74e2805afd4c1c8cb72bd8e22".to_string(),
0,
"baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc81700".to_string(),
sidan_csl_rs::builder::models::LanguageVersion::V2,
LanguageVersion::V2,
)
.mint_redeemer_value(Redeemer {
data: to_string(&json!({
Expand Down

0 comments on commit 736e8c7

Please sign in to comment.