1use crate::error::{MovementError, MovementResult};
33use crate::transaction::{EntryFunction, TransactionPayload};
34use crate::types::{AccountAddress, EntryFunctionId, MoveModuleId, TypeTag};
35use serde::Serialize;
36
37#[allow(dead_code)] #[derive(Debug, Clone)]
55pub struct InputEntryFunctionData {
56 module: MoveModuleId,
57 function: String,
58 type_args: Vec<TypeTag>,
59 args: Vec<Vec<u8>>,
60}
61
62impl InputEntryFunctionData {
63 #[allow(clippy::new_ret_no_self)] pub fn new(function_id: &str) -> InputEntryFunctionDataBuilder {
76 InputEntryFunctionDataBuilder::new(function_id)
77 }
78
79 pub fn from_parts(
86 module: MoveModuleId,
87 function: impl Into<String>,
88 ) -> InputEntryFunctionDataBuilder {
89 InputEntryFunctionDataBuilder {
90 module: Ok(module),
91 function: function.into(),
92 type_args: Vec::new(),
93 args: Vec::new(),
94 errors: Vec::new(),
95 }
96 }
97
98 pub fn transfer_apt(
115 recipient: AccountAddress,
116 amount: u64,
117 ) -> MovementResult<TransactionPayload> {
118 InputEntryFunctionData::new("0x1::aptos_account::transfer")
119 .arg(recipient)
120 .arg(amount)
121 .build()
122 }
123
124 pub fn transfer_coin(
136 coin_type: &str,
137 recipient: AccountAddress,
138 amount: u64,
139 ) -> MovementResult<TransactionPayload> {
140 InputEntryFunctionData::new("0x1::coin::transfer")
141 .type_arg(coin_type)
142 .arg(recipient)
143 .arg(amount)
144 .build()
145 }
146
147 pub fn create_account(auth_key: AccountAddress) -> MovementResult<TransactionPayload> {
157 InputEntryFunctionData::new("0x1::aptos_account::create_account")
158 .arg(auth_key)
159 .build()
160 }
161
162 pub fn rotate_authentication_key(
172 from_scheme: u8,
173 from_public_key_bytes: Vec<u8>,
174 to_scheme: u8,
175 to_public_key_bytes: Vec<u8>,
176 cap_rotate_key: Vec<u8>,
177 cap_update_table: Vec<u8>,
178 ) -> MovementResult<TransactionPayload> {
179 InputEntryFunctionData::new("0x1::account::rotate_authentication_key")
180 .arg(from_scheme)
181 .arg(from_public_key_bytes)
182 .arg(to_scheme)
183 .arg(to_public_key_bytes)
184 .arg(cap_rotate_key)
185 .arg(cap_update_table)
186 .build()
187 }
188
189 pub fn register_coin(coin_type: &str) -> MovementResult<TransactionPayload> {
199 InputEntryFunctionData::new("0x1::managed_coin::register")
200 .type_arg(coin_type)
201 .build()
202 }
203
204 pub fn publish_package(
215 metadata_serialized: Vec<u8>,
216 code: Vec<Vec<u8>>,
217 ) -> MovementResult<TransactionPayload> {
218 InputEntryFunctionData::new("0x1::code::publish_package_txn")
219 .arg(metadata_serialized)
220 .arg(code)
221 .build()
222 }
223}
224
225#[derive(Debug, Clone)]
227pub struct InputEntryFunctionDataBuilder {
228 module: Result<MoveModuleId, String>,
229 function: String,
230 type_args: Vec<TypeTag>,
231 args: Vec<Vec<u8>>,
232 errors: Vec<String>,
233}
234
235impl InputEntryFunctionDataBuilder {
236 #[must_use]
238 fn new(function_id: &str) -> Self {
239 match EntryFunctionId::from_str_strict(function_id) {
240 Ok(func_id) => Self {
241 module: Ok(func_id.module),
242 function: func_id.name.as_str().to_string(),
243 type_args: Vec::new(),
244 args: Vec::new(),
245 errors: Vec::new(),
246 },
247 Err(e) => Self {
248 module: Err(format!("Invalid function ID '{function_id}': {e}")),
249 function: String::new(),
250 type_args: Vec::new(),
251 args: Vec::new(),
252 errors: Vec::new(),
253 },
254 }
255 }
256
257 #[must_use]
270 pub fn type_arg(mut self, type_arg: &str) -> Self {
271 match TypeTag::from_str_strict(type_arg) {
272 Ok(tag) => self.type_args.push(tag),
273 Err(e) => self
274 .errors
275 .push(format!("Invalid type argument '{type_arg}': {e}")),
276 }
277 self
278 }
279
280 #[must_use]
282 pub fn type_arg_typed(mut self, type_arg: TypeTag) -> Self {
283 self.type_args.push(type_arg);
284 self
285 }
286
287 #[must_use]
289 pub fn type_args(mut self, type_args: impl IntoIterator<Item = &'static str>) -> Self {
290 for type_arg in type_args {
291 self = self.type_arg(type_arg);
292 }
293 self
294 }
295
296 #[must_use]
298 pub fn type_args_typed(mut self, type_args: impl IntoIterator<Item = TypeTag>) -> Self {
299 self.type_args.extend(type_args);
300 self
301 }
302
303 #[must_use]
326 pub fn arg<T: Serialize>(mut self, value: T) -> Self {
327 match aptos_bcs::to_bytes(&value) {
328 Ok(bytes) => self.args.push(bytes),
329 Err(e) => self
330 .errors
331 .push(format!("Failed to serialize argument: {e}")),
332 }
333 self
334 }
335
336 #[must_use]
340 pub fn arg_raw(mut self, bytes: Vec<u8>) -> Self {
341 self.args.push(bytes);
342 self
343 }
344
345 #[must_use]
347 pub fn args<T: Serialize>(mut self, values: impl IntoIterator<Item = T>) -> Self {
348 for value in values {
349 self = self.arg(value);
350 }
351 self
352 }
353
354 pub fn build(self) -> MovementResult<TransactionPayload> {
365 let module = self.module.map_err(MovementError::Transaction)?;
367
368 if !self.errors.is_empty() {
370 return Err(MovementError::Transaction(self.errors.join("; ")));
371 }
372
373 Ok(TransactionPayload::EntryFunction(EntryFunction {
374 module,
375 function: self.function,
376 type_args: self.type_args,
377 args: self.args,
378 }))
379 }
380
381 pub fn build_entry_function(self) -> MovementResult<EntryFunction> {
387 let module = self.module.map_err(MovementError::Transaction)?;
388
389 if !self.errors.is_empty() {
390 return Err(MovementError::Transaction(self.errors.join("; ")));
391 }
392
393 Ok(EntryFunction {
394 module,
395 function: self.function,
396 type_args: self.type_args,
397 args: self.args,
398 })
399 }
400}
401
402pub trait IntoMoveArg {
406 fn into_move_arg(self) -> MovementResult<Vec<u8>>;
412}
413
414impl<T: Serialize> IntoMoveArg for T {
415 fn into_move_arg(self) -> MovementResult<Vec<u8>> {
416 aptos_bcs::to_bytes(&self).map_err(MovementError::bcs)
417 }
418}
419
420pub fn move_vec<T: Serialize>(items: &[T]) -> MovementResult<Vec<u8>> {
435 aptos_bcs::to_bytes(items).map_err(MovementError::bcs)
436}
437
438pub fn move_string(s: &str) -> String {
448 s.to_string()
449}
450
451pub fn move_some<T: Serialize>(value: T) -> MovementResult<Vec<u8>> {
463 let mut bytes = vec![0x01];
465 bytes.extend(aptos_bcs::to_bytes(&value).map_err(MovementError::bcs)?);
466 Ok(bytes)
467}
468
469pub fn move_none() -> Vec<u8> {
477 vec![0x00]
479}
480
481#[derive(Debug, Clone, Copy, PartialEq, Eq)]
485pub struct MoveU256(pub [u8; 32]);
486
487impl MoveU256 {
488 pub fn parse(s: &str) -> MovementResult<Self> {
494 let mut bytes = [0u8; 32];
496
497 if let Ok(val) = s.parse::<u128>() {
499 bytes[..16].copy_from_slice(&val.to_le_bytes());
500 return Ok(Self(bytes));
501 }
502
503 Err(MovementError::Transaction(format!("Invalid u256: {s}")))
504 }
505
506 pub fn from_u128(val: u128) -> Self {
508 let mut bytes = [0u8; 32];
509 bytes[..16].copy_from_slice(&val.to_le_bytes());
510 Self(bytes)
511 }
512
513 pub fn from_le_bytes(bytes: [u8; 32]) -> Self {
515 Self(bytes)
516 }
517}
518
519impl Serialize for MoveU256 {
520 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
521 where
522 S: serde::Serializer,
523 {
524 use serde::ser::SerializeTuple;
526 let mut tuple = serializer.serialize_tuple(32)?;
527 for byte in &self.0 {
528 tuple.serialize_element(byte)?;
529 }
530 tuple.end()
531 }
532}
533
534#[derive(Debug, Clone, Copy, PartialEq, Eq)]
539pub struct MoveI128(pub i128);
540
541impl MoveI128 {
542 pub fn new(val: i128) -> Self {
544 Self(val)
545 }
546}
547
548impl Serialize for MoveI128 {
549 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
550 where
551 S: serde::Serializer,
552 {
553 use serde::ser::SerializeTuple;
555 let bytes = self.0.to_le_bytes();
556 let mut tuple = serializer.serialize_tuple(16)?;
557 for byte in &bytes {
558 tuple.serialize_element(byte)?;
559 }
560 tuple.end()
561 }
562}
563
564impl From<i128> for MoveI128 {
565 fn from(val: i128) -> Self {
566 Self(val)
567 }
568}
569
570#[derive(Debug, Clone, Copy, PartialEq, Eq)]
575pub struct MoveI256(pub [u8; 32]);
576
577impl MoveI256 {
578 pub fn from_i128(val: i128) -> Self {
580 let mut bytes = [0u8; 32];
581 let val_bytes = val.to_le_bytes();
582 bytes[..16].copy_from_slice(&val_bytes);
583 if val < 0 {
585 bytes[16..].fill(0xFF);
586 }
587 Self(bytes)
588 }
589
590 pub fn from_le_bytes(bytes: [u8; 32]) -> Self {
592 Self(bytes)
593 }
594}
595
596impl Serialize for MoveI256 {
597 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
598 where
599 S: serde::Serializer,
600 {
601 use serde::ser::SerializeTuple;
603 let mut tuple = serializer.serialize_tuple(32)?;
604 for byte in &self.0 {
605 tuple.serialize_element(byte)?;
606 }
607 tuple.end()
608 }
609}
610
611impl From<i128> for MoveI256 {
612 fn from(val: i128) -> Self {
613 Self::from_i128(val)
614 }
615}
616
617pub mod functions {
619 pub const APT_TRANSFER: &str = "0x1::aptos_account::transfer";
621 pub const COIN_TRANSFER: &str = "0x1::coin::transfer";
623 pub const CREATE_ACCOUNT: &str = "0x1::aptos_account::create_account";
625 pub const REGISTER_COIN: &str = "0x1::managed_coin::register";
627 pub const PUBLISH_PACKAGE: &str = "0x1::code::publish_package_txn";
629 pub const ROTATE_AUTH_KEY: &str = "0x1::account::rotate_authentication_key";
631}
632
633pub mod types {
635 pub const APT_COIN: &str = "0x1::aptos_coin::AptosCoin";
637}
638
639#[cfg(test)]
640mod tests {
641 use super::*;
642
643 #[test]
644 fn test_simple_transfer() {
645 let recipient = AccountAddress::from_hex("0x123").unwrap();
646 let payload = InputEntryFunctionData::new("0x1::aptos_account::transfer")
647 .arg(recipient)
648 .arg(1_000_000u64)
649 .build()
650 .unwrap();
651
652 match payload {
653 TransactionPayload::EntryFunction(ef) => {
654 assert_eq!(ef.function, "transfer");
655 assert_eq!(ef.module.name.as_str(), "aptos_account");
656 assert!(ef.type_args.is_empty());
657 assert_eq!(ef.args.len(), 2);
658 }
659 _ => panic!("Expected EntryFunction"),
660 }
661 }
662
663 #[test]
664 fn test_with_type_args() {
665 let payload = InputEntryFunctionData::new("0x1::coin::transfer")
666 .type_arg("0x1::aptos_coin::AptosCoin")
667 .arg(AccountAddress::ONE)
668 .arg(1000u64)
669 .build()
670 .unwrap();
671
672 match payload {
673 TransactionPayload::EntryFunction(ef) => {
674 assert_eq!(ef.function, "transfer");
675 assert_eq!(ef.type_args.len(), 1);
676 }
677 _ => panic!("Expected EntryFunction"),
678 }
679 }
680
681 #[test]
682 fn test_invalid_function_id() {
683 let result = InputEntryFunctionData::new("invalid").arg(42u64).build();
684
685 assert!(result.is_err());
686 }
687
688 #[test]
689 fn test_invalid_type_arg() {
690 let result = InputEntryFunctionData::new("0x1::coin::transfer")
691 .type_arg("not a type")
692 .arg(AccountAddress::ONE)
693 .arg(1000u64)
694 .build();
695
696 assert!(result.is_err());
697 }
698
699 #[test]
700 fn test_transfer_apt_helper() {
701 let recipient = AccountAddress::from_hex("0x456").unwrap();
702 let payload = InputEntryFunctionData::transfer_apt(recipient, 5_000_000).unwrap();
703
704 match payload {
705 TransactionPayload::EntryFunction(ef) => {
706 assert_eq!(ef.function, "transfer");
707 assert_eq!(ef.module.name.as_str(), "aptos_account");
708 }
709 _ => panic!("Expected EntryFunction"),
710 }
711 }
712
713 #[test]
714 fn test_transfer_coin_helper() {
715 let recipient = AccountAddress::from_hex("0x789").unwrap();
716 let payload =
717 InputEntryFunctionData::transfer_coin("0x1::aptos_coin::AptosCoin", recipient, 1000)
718 .unwrap();
719
720 match payload {
721 TransactionPayload::EntryFunction(ef) => {
722 assert_eq!(ef.function, "transfer");
723 assert_eq!(ef.module.name.as_str(), "coin");
724 assert_eq!(ef.type_args.len(), 1);
725 }
726 _ => panic!("Expected EntryFunction"),
727 }
728 }
729
730 #[test]
731 fn test_various_arg_types() {
732 let payload = InputEntryFunctionData::new("0x1::test::test_function")
733 .arg(42u8)
734 .arg(1000u64)
735 .arg(true)
736 .arg("hello".to_string())
737 .arg(vec![1u8, 2u8, 3u8])
738 .arg(AccountAddress::ONE)
739 .build()
740 .unwrap();
741
742 match payload {
743 TransactionPayload::EntryFunction(ef) => {
744 assert_eq!(ef.args.len(), 6);
745 }
746 _ => panic!("Expected EntryFunction"),
747 }
748 }
749
750 #[test]
751 fn test_move_u256() {
752 let val = MoveU256::from_u128(12345);
753 let bytes = aptos_bcs::to_bytes(&val).unwrap();
754 assert_eq!(bytes.len(), 32);
755 }
756
757 #[test]
758 fn test_move_some_none() {
759 let some_bytes = move_some(42u64).unwrap();
760 assert_eq!(some_bytes[0], 0x01);
761
762 let none_bytes = move_none();
763 assert_eq!(none_bytes, vec![0x00]);
764 }
765
766 #[test]
767 fn test_from_parts() {
768 let module = MoveModuleId::from_str_strict("0x1::coin").unwrap();
769 let payload = InputEntryFunctionData::from_parts(module, "transfer")
770 .type_arg("0x1::aptos_coin::AptosCoin")
771 .arg(AccountAddress::ONE)
772 .arg(1000u64)
773 .build()
774 .unwrap();
775
776 match payload {
777 TransactionPayload::EntryFunction(ef) => {
778 assert_eq!(ef.function, "transfer");
779 assert_eq!(ef.module.name.as_str(), "coin");
780 }
781 _ => panic!("Expected EntryFunction"),
782 }
783 }
784
785 #[test]
786 fn test_build_entry_function() {
787 let ef = InputEntryFunctionData::new("0x1::aptos_account::transfer")
788 .arg(AccountAddress::ONE)
789 .arg(1000u64)
790 .build_entry_function()
791 .unwrap();
792
793 assert_eq!(ef.function, "transfer");
794 assert_eq!(ef.args.len(), 2);
795 }
796
797 #[test]
798 fn test_function_constants() {
799 assert_eq!(functions::APT_TRANSFER, "0x1::aptos_account::transfer");
800 assert_eq!(functions::COIN_TRANSFER, "0x1::coin::transfer");
801 }
802
803 #[test]
804 fn test_move_u256_from_u128() {
805 let val = MoveU256::from_u128(123_456_789);
806 let expected = 123_456_789_u128.to_le_bytes();
808 assert_eq!(&val.0[..16], &expected);
809 assert_eq!(&val.0[16..], &[0u8; 16]);
811 }
812
813 #[test]
814 fn test_move_u256_from_le_bytes() {
815 let bytes = [0xab; 32];
816 let val = MoveU256::from_le_bytes(bytes);
817 assert_eq!(val.0, bytes);
818 }
819
820 #[test]
821 fn test_move_u256_parse() {
822 let val = MoveU256::parse("12345678901234567890").unwrap();
823 let expected = 12_345_678_901_234_567_890_u128;
824 let mut expected_bytes = [0u8; 32];
825 expected_bytes[..16].copy_from_slice(&expected.to_le_bytes());
826 assert_eq!(val.0, expected_bytes);
827 }
828
829 #[test]
830 fn test_move_u256_parse_invalid() {
831 let result = MoveU256::parse("999999999999999999999999999999999999999999999");
833 assert!(result.is_err());
834 }
835
836 #[test]
837 fn test_move_u256_serialization() {
838 let val = MoveU256::from_u128(0x0102_0304_0506_0708);
839 let bcs = aptos_bcs::to_bytes(&val).unwrap();
840 assert_eq!(bcs.len(), 32);
842 assert_eq!(&bcs[..8], &[0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01]);
844 }
845
846 #[test]
847 fn test_move_i128_new() {
848 let val = MoveI128::new(42);
849 assert_eq!(val.0, 42);
850 }
851
852 #[test]
853 fn test_move_i128_from_i128() {
854 let val: MoveI128 = (-100i128).into();
855 assert_eq!(val.0, -100);
856 }
857
858 #[test]
859 fn test_move_i128_serialization_positive() {
860 let val = MoveI128::new(0x0102_0304_0506_0708);
861 let bcs = aptos_bcs::to_bytes(&val).unwrap();
862 assert_eq!(bcs.len(), 16);
864 assert_eq!(&bcs[..8], &[0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01]);
866 assert_eq!(&bcs[8..], &[0, 0, 0, 0, 0, 0, 0, 0]);
868 }
869
870 #[test]
871 fn test_move_i128_serialization_negative() {
872 let val = MoveI128::new(-1);
873 let bcs = aptos_bcs::to_bytes(&val).unwrap();
874 assert_eq!(bcs.len(), 16);
875 assert_eq!(bcs, vec![0xFF; 16]);
877 }
878
879 #[test]
880 fn test_move_i256_from_i128_positive() {
881 let val = MoveI256::from_i128(42);
882 let expected = 42i128.to_le_bytes();
884 assert_eq!(&val.0[..16], &expected);
885 assert_eq!(&val.0[16..], &[0u8; 16]);
887 }
888
889 #[test]
890 fn test_move_i256_from_i128_negative() {
891 let val = MoveI256::from_i128(-1);
892 assert_eq!(val.0, [0xFF; 32]);
894 }
895
896 #[test]
897 fn test_move_i256_from_le_bytes() {
898 let bytes = [0xcd; 32];
899 let val = MoveI256::from_le_bytes(bytes);
900 assert_eq!(val.0, bytes);
901 }
902
903 #[test]
904 fn test_move_i256_from_trait() {
905 let val: MoveI256 = (-100i128).into();
906 let expected = MoveI256::from_i128(-100);
907 assert_eq!(val, expected);
908 }
909
910 #[test]
911 fn test_move_i256_serialization() {
912 let val = MoveI256::from_i128(0x0102_0304_0506_0708);
913 let bcs = aptos_bcs::to_bytes(&val).unwrap();
914 assert_eq!(bcs.len(), 32);
916 assert_eq!(&bcs[..8], &[0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01]);
918 }
919
920 #[test]
921 fn test_move_i256_serialization_negative() {
922 let val = MoveI256::from_i128(-1);
923 let bcs = aptos_bcs::to_bytes(&val).unwrap();
924 assert_eq!(bcs.len(), 32);
925 assert_eq!(bcs, vec![0xFF; 32]);
927 }
928
929 #[test]
930 fn test_input_entry_function_data_new() {
931 let builder = InputEntryFunctionData::new("0x1::coin::transfer");
932 let result = builder.build();
933 assert!(result.is_ok());
935 }
936
937 #[test]
938 fn test_input_entry_function_data_invalid_function_id() {
939 let builder = InputEntryFunctionData::new("invalid");
940 let result = builder.build();
941 assert!(result.is_err());
942 assert!(
943 result
944 .unwrap_err()
945 .to_string()
946 .contains("Invalid function ID")
947 );
948 }
949
950 #[test]
951 fn test_input_entry_function_data_type_arg() {
952 let builder = InputEntryFunctionData::new("0x1::coin::transfer")
953 .type_arg("0x1::aptos_coin::AptosCoin");
954 let result = builder.build();
955 assert!(result.is_ok());
956 }
957
958 #[test]
959 fn test_input_entry_function_data_invalid_type_arg() {
960 let builder =
961 InputEntryFunctionData::new("0x1::coin::transfer").type_arg("not a valid type");
962 let result = builder.build();
963 assert!(result.is_err());
964 assert!(result.unwrap_err().to_string().contains("type argument"));
965 }
966
967 #[test]
968 fn test_input_entry_function_data_type_arg_typed() {
969 use crate::types::TypeTag;
970
971 let builder =
972 InputEntryFunctionData::new("0x1::coin::transfer").type_arg_typed(TypeTag::U64);
973 let result = builder.build();
974 assert!(result.is_ok());
975 }
976
977 #[test]
978 fn test_input_entry_function_data_type_args() {
979 let builder = InputEntryFunctionData::new("0x1::coin::transfer").type_args(["u64", "u128"]);
980 let result = builder.build();
981 assert!(result.is_ok());
982 }
983
984 #[test]
985 fn test_input_entry_function_data_type_args_typed() {
986 use crate::types::TypeTag;
987
988 let builder = InputEntryFunctionData::new("0x1::coin::transfer")
989 .type_args_typed([TypeTag::U64, TypeTag::Bool]);
990 let result = builder.build();
991 assert!(result.is_ok());
992 }
993
994 #[test]
995 fn test_input_entry_function_data_arg() {
996 let builder = InputEntryFunctionData::new("0x1::coin::transfer")
997 .arg(42u64)
998 .arg(true)
999 .arg("hello".to_string());
1000 let result = builder.build();
1001 assert!(result.is_ok());
1002 }
1003
1004 #[test]
1005 fn test_input_entry_function_data_arg_raw() {
1006 let raw_bytes = vec![0x01, 0x02, 0x03];
1007 let builder = InputEntryFunctionData::new("0x1::coin::transfer").arg_raw(raw_bytes);
1008 let result = builder.build();
1009 assert!(result.is_ok());
1010 }
1011
1012 #[test]
1013 fn test_input_entry_function_data_args() {
1014 let builder = InputEntryFunctionData::new("0x1::coin::transfer").args([1u64, 2u64, 3u64]);
1015 let result = builder.build();
1016 assert!(result.is_ok());
1017 }
1018
1019 #[test]
1020 fn test_input_entry_function_data_transfer_apt() {
1021 use crate::types::AccountAddress;
1022
1023 let recipient = AccountAddress::from_hex("0x123").unwrap();
1024 let result = InputEntryFunctionData::transfer_apt(recipient, 1000);
1025 assert!(result.is_ok());
1026 }
1027
1028 #[test]
1029 fn test_input_entry_function_data_builder_debug() {
1030 let builder = InputEntryFunctionData::new("0x1::coin::transfer");
1031 let debug = format!("{builder:?}");
1032 assert!(debug.contains("InputEntryFunctionDataBuilder"));
1033 }
1034
1035 #[test]
1036 fn test_input_entry_function_data_builder_clone() {
1037 let builder = InputEntryFunctionData::new("0x1::coin::transfer").arg(42u64);
1038 let cloned = builder.clone();
1039 assert!(cloned.build().is_ok());
1040 }
1041
1042 #[test]
1043 fn test_move_u256_debug() {
1044 let val = MoveU256::from_u128(123_456_789);
1045 let debug = format!("{val:?}");
1046 assert!(debug.contains("MoveU256"));
1047 }
1048
1049 #[test]
1050 fn test_move_i128_debug() {
1051 let val = MoveI128::new(-42);
1052 let debug = format!("{val:?}");
1053 assert!(debug.contains("MoveI128"));
1054 }
1055
1056 #[test]
1057 fn test_move_i256_debug() {
1058 let val = MoveI256::from_i128(-42);
1059 let debug = format!("{val:?}");
1060 assert!(debug.contains("MoveI256"));
1061 }
1062
1063 #[test]
1064 fn test_move_u256_equality() {
1065 let val1 = MoveU256::from_u128(100);
1066 let val2 = MoveU256::from_u128(100);
1067 let val3 = MoveU256::from_u128(200);
1068 assert_eq!(val1, val2);
1069 assert_ne!(val1, val3);
1070 }
1071
1072 #[test]
1073 fn test_move_i256_equality() {
1074 let val1 = MoveI256::from_i128(-50);
1075 let val2 = MoveI256::from_i128(-50);
1076 let val3 = MoveI256::from_i128(50);
1077 assert_eq!(val1, val2);
1078 assert_ne!(val1, val3);
1079 }
1080
1081 #[test]
1082 fn test_move_u256_clone() {
1083 let val1 = MoveU256::from_u128(999);
1084 let val2 = val1;
1085 assert_eq!(val1, val2);
1086 }
1087
1088 #[test]
1089 fn test_move_i256_clone() {
1090 let val1 = MoveI256::from_i128(-999);
1091 let val2 = val1;
1092 assert_eq!(val1, val2);
1093 }
1094}