Skip to content

Commit d2a1acb

Browse files
authored
Merge pull request #233 from algorandfoundation/chore/ffi-txn-types
chore: extract FFI txn types out of lib.rs
2 parents 62b4810 + d903a80 commit d2a1acb

File tree

6 files changed

+181
-156
lines changed

6 files changed

+181
-156
lines changed

crates/algokit_transact_ffi/src/lib.rs

Lines changed: 3 additions & 153 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ pub use multisig::{MultisigSignature, MultisigSubsignature};
1313
pub use transactions::ApplicationCallTransactionFields;
1414
pub use transactions::AssetConfigTransactionFields;
1515
pub use transactions::AssetFreezeTransactionFields;
16+
pub use transactions::AssetTransferTransactionFields;
1617
pub use transactions::KeyRegistrationTransactionFields;
18+
pub use transactions::PaymentTransactionFields;
1719

1820
// thiserror is used to easily create errors than can be propagated to the language bindings
1921
// UniFFI will create classes for errors (i.e. `MsgPackError.EncodingError` in Python)
@@ -172,28 +174,6 @@ pub struct FeeParams {
172174
max_fee: Option<u64>,
173175
}
174176

175-
#[ffi_record]
176-
pub struct PaymentTransactionFields {
177-
receiver: String,
178-
179-
amount: u64,
180-
181-
close_remainder_to: Option<String>,
182-
}
183-
184-
#[ffi_record]
185-
pub struct AssetTransferTransactionFields {
186-
asset_id: u64,
187-
188-
amount: u64,
189-
190-
receiver: String,
191-
192-
asset_sender: Option<String>,
193-
194-
close_remainder_to: Option<String>,
195-
}
196-
197177
#[ffi_record]
198178
pub struct Transaction {
199179
/// The type of transaction
@@ -310,80 +290,6 @@ impl TryFrom<Transaction> for algokit_transact::TransactionHeader {
310290
}
311291
}
312292

313-
impl From<algokit_transact::PaymentTransactionFields> for PaymentTransactionFields {
314-
fn from(tx: algokit_transact::PaymentTransactionFields) -> Self {
315-
Self {
316-
receiver: tx.receiver.as_str(),
317-
amount: tx.amount,
318-
close_remainder_to: tx.close_remainder_to.map(|addr| addr.as_str()),
319-
}
320-
}
321-
}
322-
323-
impl TryFrom<Transaction> for algokit_transact::PaymentTransactionFields {
324-
type Error = AlgoKitTransactError;
325-
326-
fn try_from(tx: Transaction) -> Result<Self, Self::Error> {
327-
if tx.transaction_type != TransactionType::Payment || tx.payment.is_none() {
328-
return Err(Self::Error::DecodingError(
329-
"Payment data missing".to_string(),
330-
));
331-
}
332-
333-
let data = tx.clone().payment.unwrap();
334-
let header: algokit_transact::TransactionHeader = tx.try_into()?;
335-
336-
Ok(Self {
337-
header,
338-
amount: data.amount,
339-
receiver: data.receiver.parse()?,
340-
close_remainder_to: data
341-
.close_remainder_to
342-
.map(|addr| addr.parse())
343-
.transpose()?,
344-
})
345-
}
346-
}
347-
348-
impl From<algokit_transact::AssetTransferTransactionFields> for AssetTransferTransactionFields {
349-
fn from(tx: algokit_transact::AssetTransferTransactionFields) -> Self {
350-
Self {
351-
asset_id: tx.asset_id,
352-
amount: tx.amount,
353-
receiver: tx.receiver.as_str(),
354-
asset_sender: tx.asset_sender.map(|addr| addr.as_str()),
355-
close_remainder_to: tx.close_remainder_to.map(|addr| addr.as_str()),
356-
}
357-
}
358-
}
359-
360-
impl TryFrom<Transaction> for algokit_transact::AssetTransferTransactionFields {
361-
type Error = AlgoKitTransactError;
362-
363-
fn try_from(tx: Transaction) -> Result<Self, Self::Error> {
364-
if tx.transaction_type != TransactionType::AssetTransfer || tx.asset_transfer.is_none() {
365-
return Err(Self::Error::DecodingError(
366-
"Asset Transfer data missing".to_string(),
367-
));
368-
}
369-
370-
let data = tx.clone().asset_transfer.unwrap();
371-
let header: algokit_transact::TransactionHeader = tx.try_into()?;
372-
373-
Ok(Self {
374-
header,
375-
asset_id: data.asset_id,
376-
amount: data.amount,
377-
receiver: data.receiver.parse()?,
378-
asset_sender: data.asset_sender.map(|addr| addr.parse()).transpose()?,
379-
close_remainder_to: data
380-
.close_remainder_to
381-
.map(|addr| addr.parse())
382-
.transpose()?,
383-
})
384-
}
385-
}
386-
387293
impl TryFrom<algokit_transact::Transaction> for Transaction {
388294
type Error = AlgoKitTransactError;
389295

@@ -943,65 +849,9 @@ pub fn encode_signed_transactions(
943849
#[cfg(test)]
944850
mod tests {
945851
use super::*;
946-
use algokit_transact::test_utils::{TestDataMother, TransactionMother};
852+
use algokit_transact::test_utils::TestDataMother;
947853
use pretty_assertions::assert_eq;
948854

949-
#[test]
950-
fn test_get_encoded_payment_transaction_type() {
951-
let txn: Transaction = TransactionMother::simple_payment()
952-
.build()
953-
.unwrap()
954-
.try_into()
955-
.unwrap();
956-
957-
// Encode the transaction
958-
let encoded = encode_transaction(txn).unwrap();
959-
960-
// Test the get_encoded_transaction_type function
961-
let tx_type = get_encoded_transaction_type(&encoded).unwrap();
962-
assert_eq!(tx_type, TransactionType::Payment);
963-
}
964-
965-
#[test]
966-
fn test_get_encoded_asset_transfer_transaction_type() {
967-
let txn: Transaction = TransactionMother::simple_asset_transfer()
968-
.build()
969-
.unwrap()
970-
.try_into()
971-
.unwrap();
972-
973-
// Encode the transaction
974-
let encoded = encode_transaction(txn).unwrap();
975-
976-
// Test the get_encoded_transaction_type function
977-
let tx_type = get_encoded_transaction_type(&encoded).unwrap();
978-
assert_eq!(tx_type, TransactionType::AssetTransfer);
979-
}
980-
981-
#[test]
982-
fn test_payment_transaction_id_ffi() {
983-
let data = TestDataMother::simple_payment();
984-
let tx_ffi: Transaction = data.transaction.try_into().unwrap();
985-
986-
let actual_id = get_transaction_id(tx_ffi.clone()).unwrap();
987-
let actual_id_raw = get_transaction_id_raw(tx_ffi.clone()).unwrap();
988-
989-
assert_eq!(actual_id, data.id);
990-
assert_eq!(actual_id_raw, data.id_raw);
991-
}
992-
993-
#[test]
994-
fn test_asset_transfer_transaction_id_ffi() {
995-
let data = TestDataMother::simple_asset_transfer();
996-
let tx_ffi: Transaction = data.transaction.try_into().unwrap();
997-
998-
let actual_id = get_transaction_id(tx_ffi.clone()).unwrap();
999-
let actual_id_raw = get_transaction_id_raw(tx_ffi.clone()).unwrap();
1000-
1001-
assert_eq!(actual_id, data.id);
1002-
assert_eq!(actual_id_raw, data.id_raw);
1003-
}
1004-
1005855
#[test]
1006856
fn test_group_transactions_ffi() {
1007857
let expected_group = [
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
use crate::*;
2+
3+
#[ffi_record]
4+
pub struct AssetTransferTransactionFields {
5+
asset_id: u64,
6+
7+
amount: u64,
8+
9+
receiver: String,
10+
11+
asset_sender: Option<String>,
12+
13+
close_remainder_to: Option<String>,
14+
}
15+
16+
impl From<algokit_transact::AssetTransferTransactionFields> for AssetTransferTransactionFields {
17+
fn from(tx: algokit_transact::AssetTransferTransactionFields) -> Self {
18+
Self {
19+
asset_id: tx.asset_id,
20+
amount: tx.amount,
21+
receiver: tx.receiver.as_str(),
22+
asset_sender: tx.asset_sender.map(|addr| addr.as_str()),
23+
close_remainder_to: tx.close_remainder_to.map(|addr| addr.as_str()),
24+
}
25+
}
26+
}
27+
28+
impl TryFrom<Transaction> for algokit_transact::AssetTransferTransactionFields {
29+
type Error = AlgoKitTransactError;
30+
31+
fn try_from(tx: Transaction) -> Result<Self, Self::Error> {
32+
if tx.transaction_type != TransactionType::AssetTransfer || tx.asset_transfer.is_none() {
33+
return Err(Self::Error::DecodingError(
34+
"Asset Transfer data missing".to_string(),
35+
));
36+
}
37+
38+
let data = tx.clone().asset_transfer.unwrap();
39+
let header: algokit_transact::TransactionHeader = tx.try_into()?;
40+
41+
Ok(Self {
42+
header,
43+
asset_id: data.asset_id,
44+
amount: data.amount,
45+
receiver: data.receiver.parse()?,
46+
asset_sender: data.asset_sender.map(|addr| addr.parse()).transpose()?,
47+
close_remainder_to: data
48+
.close_remainder_to
49+
.map(|addr| addr.parse())
50+
.transpose()?,
51+
})
52+
}
53+
}
54+
55+
#[cfg(test)]
56+
mod tests {
57+
use super::*;
58+
use algokit_transact::test_utils::{TestDataMother, TransactionMother};
59+
use pretty_assertions::assert_eq;
60+
61+
#[test]
62+
fn test_get_encoded_asset_transfer_transaction_type() {
63+
let txn: Transaction = TransactionMother::simple_asset_transfer()
64+
.build()
65+
.unwrap()
66+
.try_into()
67+
.unwrap();
68+
69+
// Encode the transaction
70+
let encoded = encode_transaction(txn).unwrap();
71+
72+
// Test the get_encoded_transaction_type function
73+
let tx_type = get_encoded_transaction_type(&encoded).unwrap();
74+
assert_eq!(tx_type, TransactionType::AssetTransfer);
75+
}
76+
77+
#[test]
78+
fn test_asset_transfer_transaction_id_ffi() {
79+
let data = TestDataMother::simple_asset_transfer();
80+
let tx_ffi: Transaction = data.transaction.try_into().unwrap();
81+
82+
let actual_id = get_transaction_id(tx_ffi.clone()).unwrap();
83+
let actual_id_raw = get_transaction_id_raw(tx_ffi.clone()).unwrap();
84+
85+
assert_eq!(actual_id, data.id);
86+
assert_eq!(actual_id_raw, data.id_raw);
87+
}
88+
}

crates/algokit_transact_ffi/src/transactions/mod.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ pub mod asset_freeze;
55
pub use application_call::ApplicationCallTransactionFields;
66
pub use asset_config::AssetConfigTransactionFields;
77

8-
pub mod keyreg;
8+
pub mod key_registration;
99
pub use asset_freeze::AssetFreezeTransactionFields;
10-
pub use keyreg::KeyRegistrationTransactionFields;
10+
pub use key_registration::KeyRegistrationTransactionFields;
11+
12+
pub mod payment;
13+
pub use payment::PaymentTransactionFields;
14+
15+
pub mod asset_transfer;
16+
pub use asset_transfer::AssetTransferTransactionFields;
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
use crate::*;
2+
3+
#[ffi_record]
4+
pub struct PaymentTransactionFields {
5+
receiver: String,
6+
7+
amount: u64,
8+
9+
close_remainder_to: Option<String>,
10+
}
11+
12+
impl From<algokit_transact::PaymentTransactionFields> for PaymentTransactionFields {
13+
fn from(tx: algokit_transact::PaymentTransactionFields) -> Self {
14+
Self {
15+
receiver: tx.receiver.as_str(),
16+
amount: tx.amount,
17+
close_remainder_to: tx.close_remainder_to.map(|addr| addr.as_str()),
18+
}
19+
}
20+
}
21+
22+
impl TryFrom<Transaction> for algokit_transact::PaymentTransactionFields {
23+
type Error = AlgoKitTransactError;
24+
25+
fn try_from(tx: Transaction) -> Result<Self, Self::Error> {
26+
if tx.transaction_type != TransactionType::Payment || tx.payment.is_none() {
27+
return Err(Self::Error::DecodingError(
28+
"Payment data missing".to_string(),
29+
));
30+
}
31+
32+
let data = tx.clone().payment.unwrap();
33+
let header: algokit_transact::TransactionHeader = tx.try_into()?;
34+
35+
Ok(Self {
36+
header,
37+
amount: data.amount,
38+
receiver: data.receiver.parse()?,
39+
close_remainder_to: data
40+
.close_remainder_to
41+
.map(|addr| addr.parse())
42+
.transpose()?,
43+
})
44+
}
45+
}
46+
47+
#[cfg(test)]
48+
mod tests {
49+
use super::*;
50+
use algokit_transact::test_utils::{TestDataMother, TransactionMother};
51+
use pretty_assertions::assert_eq;
52+
53+
#[test]
54+
fn test_get_encoded_payment_transaction_type() {
55+
let txn: Transaction = TransactionMother::simple_payment()
56+
.build()
57+
.unwrap()
58+
.try_into()
59+
.unwrap();
60+
61+
// Encode the transaction
62+
let encoded = encode_transaction(txn).unwrap();
63+
64+
// Test the get_encoded_transaction_type function
65+
let tx_type = get_encoded_transaction_type(&encoded).unwrap();
66+
assert_eq!(tx_type, TransactionType::Payment);
67+
}
68+
69+
#[test]
70+
fn test_payment_transaction_id_ffi() {
71+
let data = TestDataMother::simple_payment();
72+
let tx_ffi: Transaction = data.transaction.try_into().unwrap();
73+
74+
let actual_id = get_transaction_id(tx_ffi.clone()).unwrap();
75+
let actual_id_raw = get_transaction_id_raw(tx_ffi.clone()).unwrap();
76+
77+
assert_eq!(actual_id, data.id);
78+
assert_eq!(actual_id_raw, data.id_raw);
79+
}
80+
}

packages/python/algokit_transact/tests/test_asset_config.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
assert_encode_with_signature,
99
assert_encoded_transaction_type,
1010
assert_example,
11-
assert_transaction_id, assert_multisig_example,
11+
assert_transaction_id,
12+
assert_multisig_example,
1213
)
1314

1415
from . import TEST_DATA

0 commit comments

Comments
 (0)