Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions crates/algokit_transact/src/test_utils/asset_freeze.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
use crate::{Address, AssetFreezeTransactionBuilder, Byte32, TransactionHeaderBuilder};
use base64::{prelude::BASE64_STANDARD, Engine};

pub struct AssetFreezeTransactionMother {}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test data builder for asset freeze are refactored to another file, similar to https://github.com/algorandfoundation/algokit-core/blob/main/crates/algokit_transact/src/test_utils/asset_config.rs


impl AssetFreezeTransactionMother {
pub fn asset_freeze() -> AssetFreezeTransactionBuilder {
// mainnet-2XFGVOHMFYLAWBHOSIOI67PBT5LDRHBTD3VLX5EYBDTFNVKMCJIA
let sender = "E4A6FVIHXSZ3F7QXRCOTYDDILVQYEBFH56HYDIIYX4SVXS2QX5GUTBVZHY"
.parse::<Address>()
.unwrap();
let freeze_address = "ZJU3X2B2QN3BUBIJ64JZ565V363ANGBUDOLXAJHDXGIIMYK6WV3NSNCBQQ"
.parse::<Address>()
.unwrap();
let genesis_hash: Byte32 = BASE64_STANDARD
.decode("wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiC1qzkkit8=")
.unwrap()
.try_into()
.unwrap();
let note = BASE64_STANDARD
.decode("TkZUIGZyZWV6ZWQgYnkgbG9mdHkuYWk=")
.unwrap();
let group = BASE64_STANDARD
.decode("xERjxVTlNb8jeHa16qmpxDMh4+dcDCokO69QnNESbFk=")
.unwrap()
.try_into()
.unwrap();

AssetFreezeTransactionBuilder::default()
.header(
TransactionHeaderBuilder::default()
.sender(sender)
.fee(1000)
.first_valid(37463562)
.last_valid(37464562)
.genesis_hash(genesis_hash)
.genesis_id("mainnet-v1.0".to_string())
.note(note)
.group(group)
.build()
.unwrap(),
)
.asset_id(1707148495)
.freeze_target(freeze_address)
.frozen(true)
.to_owned()
}

pub fn asset_unfreeze() -> AssetFreezeTransactionBuilder {
// testnet-LZ2ODDAT4ATAVJUEQW34DIKMPCMBXCCHOSIYKMWGBPEVNHLSEV2A
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An asset unfreeze transaction is built with real data from testnet. This allows us to confirm that our encoding is correct.

let sender = "WLH5LELVSEVQL45LBRQYCLJAX6KQPGWUY5WHJXVRV2NPYZUBQAFPH22Q7A"
.parse::<Address>()
.unwrap();
let freeze_address = "ZYQX7BZ6LGTD7UCS7J5RVEAKHUJPK3FNJFZV2GPUYS2TFIADVFHDBKTN7I"
.parse::<Address>()
.unwrap();
let genesis_hash: Byte32 = BASE64_STANDARD
.decode("SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=")
.unwrap()
.try_into()
.unwrap();
let note = BASE64_STANDARD.decode("th4JDxFROQw=").unwrap();

AssetFreezeTransactionBuilder::default()
.header(
TransactionHeaderBuilder::default()
.sender(sender)
.fee(1000)
.first_valid(3277583)
.last_valid(3278583)
.genesis_hash(genesis_hash)
.note(note)
.build()
.unwrap(),
)
.asset_id(185)
.freeze_target(freeze_address)
.frozen(false)
.to_owned()
}
}
114 changes: 19 additions & 95 deletions crates/algokit_transact/src/test_utils/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
mod application_call;
mod asset_config;
mod asset_freeze;
mod key_registration;

use crate::{
transactions::{
AssetFreezeTransactionBuilder, AssetTransferTransactionBuilder, PaymentTransactionBuilder,
},
transactions::{AssetTransferTransactionBuilder, PaymentTransactionBuilder},
Address, AlgorandMsgpack, Byte32, SignedTransaction, Transaction, TransactionHeaderBuilder,
TransactionId, ALGORAND_PUBLIC_KEY_BYTE_LENGTH, HASH_BYTES_LENGTH,
};
Expand All @@ -19,6 +18,7 @@ use std::{fs::File, str::FromStr};

pub use application_call::ApplicationCallTransactionMother;
pub use asset_config::AssetConfigTransactionMother;
pub use asset_freeze::AssetFreezeTransactionMother;
pub use key_registration::KeyRegistrationTransactionMother;

pub struct TransactionHeaderMother {}
Expand Down Expand Up @@ -160,90 +160,6 @@ impl TransactionMother {
.receiver(AddressMother::neil())
.to_owned()
}

pub fn asset_freeze() -> AssetFreezeTransactionBuilder {
// mainnet-2XFGVOHMFYLAWBHOSIOI67PBT5LDRHBTD3VLX5EYBDTFNVKMCJIA
let sender = "E4A6FVIHXSZ3F7QXRCOTYDDILVQYEBFH56HYDIIYX4SVXS2QX5GUTBVZHY"
.parse::<Address>()
.unwrap();
let freeze_address = "ZJU3X2B2QN3BUBIJ64JZ565V363ANGBUDOLXAJHDXGIIMYK6WV3NSNCBQQ"
.parse::<Address>()
.unwrap();
let genesis_hash: Byte32 = BASE64_STANDARD
.decode("wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiC1qzkkit8=")
.unwrap()
.try_into()
.unwrap();
let note = BASE64_STANDARD
.decode("TkZUIGZyZWV6ZWQgYnkgbG9mdHkuYWk=")
.unwrap();
let group = BASE64_STANDARD
.decode("xERjxVTlNb8jeHa16qmpxDMh4+dcDCokO69QnNESbFk=")
.unwrap()
.try_into()
.unwrap();

AssetFreezeTransactionBuilder::default()
.header(
TransactionHeaderBuilder::default()
.sender(sender)
.fee(1000)
.first_valid(37463562)
.last_valid(37464562)
.genesis_hash(genesis_hash)
.genesis_id("mainnet-v1.0".to_string())
.note(note)
.group(group)
.build()
.unwrap(),
)
.asset_id(1707148495)
.freeze_target(freeze_address)
.frozen(true)
.to_owned()
}

pub fn asset_unfreeze() -> AssetFreezeTransactionBuilder {
// Same as asset_freeze but with frozen=false
let sender = "E4A6FVIHXSZ3F7QXRCOTYDDILVQYEBFH56HYDIIYX4SVXS2QX5GUTBVZHY"
.parse::<Address>()
.unwrap();
let freeze_address = "ZJU3X2B2QN3BUBIJ64JZ565V363ANGBUDOLXAJHDXGIIMYK6WV3NSNCBQQ"
.parse::<Address>()
.unwrap();
let genesis_hash: Byte32 = BASE64_STANDARD
.decode("wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiC1qzkkit8=")
.unwrap()
.try_into()
.unwrap();
let note = BASE64_STANDARD
.decode("TkZUIGZyZWV6ZWQgYnkgbG9mdHkuYWk=")
.unwrap();
let group = BASE64_STANDARD
.decode("xERjxVTlNb8jeHa16qmpxDMh4+dcDCokO69QnNESbFk=")
.unwrap()
.try_into()
.unwrap();

AssetFreezeTransactionBuilder::default()
.header(
TransactionHeaderBuilder::default()
.sender(sender)
.fee(1000)
.first_valid(37463562)
.last_valid(37464562)
.genesis_hash(genesis_hash)
.genesis_id("mainnet-v1.0".to_string())
.note(note)
.group(group)
.build()
.unwrap(),
)
.asset_id(1707148495)
.freeze_target(freeze_address)
.frozen(false)
.to_owned()
}
}

pub struct AddressMother {}
Expand Down Expand Up @@ -501,7 +417,9 @@ impl TestDataMother {
2, 205, 103, 33, 67, 14, 82, 196, 115, 196, 206, 254, 50, 110, 63, 182, 149, 229, 184,
216, 93, 11, 13, 99, 69, 213, 218, 165, 134, 118, 47, 44,
];
let transaction = TransactionMother::asset_freeze().build().unwrap();
let transaction = AssetFreezeTransactionMother::asset_freeze()
.build()
.unwrap();
TransactionTestData::new(transaction, signing_private_key)
}

Expand All @@ -510,7 +428,9 @@ impl TestDataMother {
2, 205, 103, 33, 67, 14, 82, 196, 115, 196, 206, 254, 50, 110, 63, 182, 149, 229, 184,
216, 93, 11, 13, 99, 69, 213, 218, 165, 134, 118, 47, 44,
];
let transaction = TransactionMother::asset_unfreeze().build().unwrap();
let transaction = AssetFreezeTransactionMother::asset_unfreeze()
.build()
.unwrap();
TransactionTestData::new(transaction, signing_private_key)
}

Expand Down Expand Up @@ -554,17 +474,12 @@ fn normalise_json(value: serde_json::Value) -> serde_json::Value {
"num_uints",
];

// Boolean fields that should always be included, even when false
const BOOLEAN_FIELDS_TO_KEEP: &[&str] = &["frozen"];

match value {
serde_json::Value::Object(map) => serde_json::Value::Object(
map.into_iter()
.filter(|(k, v)| {
!(v.is_null()
|| v.is_boolean()
&& v.as_bool() == Some(false)
&& !BOOLEAN_FIELDS_TO_KEEP.contains(&k.to_case(Case::Snake).as_str())
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not needed, the defaultReviver in TypeScript and Python should set it to false if undefined.

|| v.is_boolean() && v.as_bool() == Some(false)
|| v.is_number()
&& v.as_u64() == Some(0)
&& !ZERO_VALUE_EXCLUDED_FIELDS
Expand Down Expand Up @@ -708,4 +623,13 @@ mod tests {
String::from("2XFGVOHMFYLAWBHOSIOI67PBT5LDRHBTD3VLX5EYBDTFNVKMCJIA")
);
}

#[test]
fn test_asset_unfreeze_snapshot() {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test snapshot to make sure that the encoding logic is correct.

let data = TestDataMother::asset_unfreeze();
assert_eq!(
data.id,
String::from("LZ2ODDAT4ATAVJUEQW34DIKMPCMBXCCHOSIYKMWGBPEVNHLSEV2A")
);
}
}
Loading