1use crate::error::{AptosError, AptosResult};
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(recipient: AccountAddress, amount: u64) -> AptosResult<TransactionPayload> {
115 InputEntryFunctionData::new("0x1::aptos_account::transfer")
116 .arg(recipient)
117 .arg(amount)
118 .build()
119 }
120
121 pub fn transfer_coin(
133 coin_type: &str,
134 recipient: AccountAddress,
135 amount: u64,
136 ) -> AptosResult<TransactionPayload> {
137 InputEntryFunctionData::new("0x1::coin::transfer")
138 .type_arg(coin_type)
139 .arg(recipient)
140 .arg(amount)
141 .build()
142 }
143
144 pub fn create_account(auth_key: AccountAddress) -> AptosResult<TransactionPayload> {
154 InputEntryFunctionData::new("0x1::aptos_account::create_account")
155 .arg(auth_key)
156 .build()
157 }
158
159 pub fn rotate_authentication_key(
169 from_scheme: u8,
170 from_public_key_bytes: Vec<u8>,
171 to_scheme: u8,
172 to_public_key_bytes: Vec<u8>,
173 cap_rotate_key: Vec<u8>,
174 cap_update_table: Vec<u8>,
175 ) -> AptosResult<TransactionPayload> {
176 InputEntryFunctionData::new("0x1::account::rotate_authentication_key")
177 .arg(from_scheme)
178 .arg(from_public_key_bytes)
179 .arg(to_scheme)
180 .arg(to_public_key_bytes)
181 .arg(cap_rotate_key)
182 .arg(cap_update_table)
183 .build()
184 }
185
186 pub fn register_coin(coin_type: &str) -> AptosResult<TransactionPayload> {
196 InputEntryFunctionData::new("0x1::managed_coin::register")
197 .type_arg(coin_type)
198 .build()
199 }
200
201 pub fn publish_package(
212 metadata_serialized: Vec<u8>,
213 code: Vec<Vec<u8>>,
214 ) -> AptosResult<TransactionPayload> {
215 InputEntryFunctionData::new("0x1::code::publish_package_txn")
216 .arg(metadata_serialized)
217 .arg(code)
218 .build()
219 }
220}
221
222#[derive(Debug, Clone)]
224pub struct InputEntryFunctionDataBuilder {
225 module: Result<MoveModuleId, String>,
226 function: String,
227 type_args: Vec<TypeTag>,
228 args: Vec<Vec<u8>>,
229 errors: Vec<String>,
230}
231
232impl InputEntryFunctionDataBuilder {
233 #[must_use]
235 fn new(function_id: &str) -> Self {
236 match EntryFunctionId::from_str_strict(function_id) {
237 Ok(func_id) => Self {
238 module: Ok(func_id.module),
239 function: func_id.name.as_str().to_string(),
240 type_args: Vec::new(),
241 args: Vec::new(),
242 errors: Vec::new(),
243 },
244 Err(e) => Self {
245 module: Err(format!("Invalid function ID '{function_id}': {e}")),
246 function: String::new(),
247 type_args: Vec::new(),
248 args: Vec::new(),
249 errors: Vec::new(),
250 },
251 }
252 }
253
254 #[must_use]
267 pub fn type_arg(mut self, type_arg: &str) -> Self {
268 match TypeTag::from_str_strict(type_arg) {
269 Ok(tag) => self.type_args.push(tag),
270 Err(e) => self
271 .errors
272 .push(format!("Invalid type argument '{type_arg}': {e}")),
273 }
274 self
275 }
276
277 #[must_use]
279 pub fn type_arg_typed(mut self, type_arg: TypeTag) -> Self {
280 self.type_args.push(type_arg);
281 self
282 }
283
284 #[must_use]
286 pub fn type_args(mut self, type_args: impl IntoIterator<Item = &'static str>) -> Self {
287 for type_arg in type_args {
288 self = self.type_arg(type_arg);
289 }
290 self
291 }
292
293 #[must_use]
295 pub fn type_args_typed(mut self, type_args: impl IntoIterator<Item = TypeTag>) -> Self {
296 self.type_args.extend(type_args);
297 self
298 }
299
300 #[must_use]
323 pub fn arg<T: Serialize>(mut self, value: T) -> Self {
324 match aptos_bcs::to_bytes(&value) {
325 Ok(bytes) => self.args.push(bytes),
326 Err(e) => self
327 .errors
328 .push(format!("Failed to serialize argument: {e}")),
329 }
330 self
331 }
332
333 #[must_use]
337 pub fn arg_raw(mut self, bytes: Vec<u8>) -> Self {
338 self.args.push(bytes);
339 self
340 }
341
342 #[must_use]
344 pub fn args<T: Serialize>(mut self, values: impl IntoIterator<Item = T>) -> Self {
345 for value in values {
346 self = self.arg(value);
347 }
348 self
349 }
350
351 pub fn build(self) -> AptosResult<TransactionPayload> {
362 let module = self.module.map_err(AptosError::Transaction)?;
364
365 if !self.errors.is_empty() {
367 return Err(AptosError::Transaction(self.errors.join("; ")));
368 }
369
370 Ok(TransactionPayload::EntryFunction(EntryFunction {
371 module,
372 function: self.function,
373 type_args: self.type_args,
374 args: self.args,
375 }))
376 }
377
378 pub fn build_entry_function(self) -> AptosResult<EntryFunction> {
384 let module = self.module.map_err(AptosError::Transaction)?;
385
386 if !self.errors.is_empty() {
387 return Err(AptosError::Transaction(self.errors.join("; ")));
388 }
389
390 Ok(EntryFunction {
391 module,
392 function: self.function,
393 type_args: self.type_args,
394 args: self.args,
395 })
396 }
397}
398
399pub trait IntoMoveArg {
403 fn into_move_arg(self) -> AptosResult<Vec<u8>>;
409}
410
411impl<T: Serialize> IntoMoveArg for T {
412 fn into_move_arg(self) -> AptosResult<Vec<u8>> {
413 aptos_bcs::to_bytes(&self).map_err(AptosError::bcs)
414 }
415}
416
417pub fn move_vec<T: Serialize>(items: &[T]) -> Vec<u8> {
428 aptos_bcs::to_bytes(items).unwrap_or_default()
429}
430
431pub fn move_string(s: &str) -> String {
441 s.to_string()
442}
443
444pub fn move_some<T: Serialize>(value: T) -> Vec<u8> {
452 let mut bytes = vec![0x01];
454 if let Ok(value_bytes) = aptos_bcs::to_bytes(&value) {
455 bytes.extend(value_bytes);
456 }
457 bytes
458}
459
460pub fn move_none() -> Vec<u8> {
468 vec![0x00]
470}
471
472#[derive(Debug, Clone, Copy, PartialEq, Eq)]
476pub struct MoveU256(pub [u8; 32]);
477
478impl MoveU256 {
479 pub fn parse(s: &str) -> AptosResult<Self> {
485 let mut bytes = [0u8; 32];
487
488 if let Ok(val) = s.parse::<u128>() {
490 bytes[..16].copy_from_slice(&val.to_le_bytes());
491 return Ok(Self(bytes));
492 }
493
494 Err(AptosError::Transaction(format!("Invalid u256: {s}")))
495 }
496
497 pub fn from_u128(val: u128) -> Self {
499 let mut bytes = [0u8; 32];
500 bytes[..16].copy_from_slice(&val.to_le_bytes());
501 Self(bytes)
502 }
503
504 pub fn from_le_bytes(bytes: [u8; 32]) -> Self {
506 Self(bytes)
507 }
508}
509
510impl Serialize for MoveU256 {
511 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
512 where
513 S: serde::Serializer,
514 {
515 use serde::ser::SerializeTuple;
517 let mut tuple = serializer.serialize_tuple(32)?;
518 for byte in &self.0 {
519 tuple.serialize_element(byte)?;
520 }
521 tuple.end()
522 }
523}
524
525#[derive(Debug, Clone, Copy, PartialEq, Eq)]
530pub struct MoveI128(pub i128);
531
532impl MoveI128 {
533 pub fn new(val: i128) -> Self {
535 Self(val)
536 }
537}
538
539impl Serialize for MoveI128 {
540 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
541 where
542 S: serde::Serializer,
543 {
544 use serde::ser::SerializeTuple;
546 let bytes = self.0.to_le_bytes();
547 let mut tuple = serializer.serialize_tuple(16)?;
548 for byte in &bytes {
549 tuple.serialize_element(byte)?;
550 }
551 tuple.end()
552 }
553}
554
555impl From<i128> for MoveI128 {
556 fn from(val: i128) -> Self {
557 Self(val)
558 }
559}
560
561#[derive(Debug, Clone, Copy, PartialEq, Eq)]
566pub struct MoveI256(pub [u8; 32]);
567
568impl MoveI256 {
569 pub fn from_i128(val: i128) -> Self {
571 let mut bytes = [0u8; 32];
572 let val_bytes = val.to_le_bytes();
573 bytes[..16].copy_from_slice(&val_bytes);
574 if val < 0 {
576 bytes[16..].fill(0xFF);
577 }
578 Self(bytes)
579 }
580
581 pub fn from_le_bytes(bytes: [u8; 32]) -> Self {
583 Self(bytes)
584 }
585}
586
587impl Serialize for MoveI256 {
588 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
589 where
590 S: serde::Serializer,
591 {
592 use serde::ser::SerializeTuple;
594 let mut tuple = serializer.serialize_tuple(32)?;
595 for byte in &self.0 {
596 tuple.serialize_element(byte)?;
597 }
598 tuple.end()
599 }
600}
601
602impl From<i128> for MoveI256 {
603 fn from(val: i128) -> Self {
604 Self::from_i128(val)
605 }
606}
607
608pub mod functions {
610 pub const APT_TRANSFER: &str = "0x1::aptos_account::transfer";
612 pub const COIN_TRANSFER: &str = "0x1::coin::transfer";
614 pub const CREATE_ACCOUNT: &str = "0x1::aptos_account::create_account";
616 pub const REGISTER_COIN: &str = "0x1::managed_coin::register";
618 pub const PUBLISH_PACKAGE: &str = "0x1::code::publish_package_txn";
620 pub const ROTATE_AUTH_KEY: &str = "0x1::account::rotate_authentication_key";
622}
623
624pub mod types {
626 pub const APT_COIN: &str = "0x1::aptos_coin::AptosCoin";
628}
629
630#[cfg(test)]
631mod tests {
632 use super::*;
633
634 #[test]
635 fn test_simple_transfer() {
636 let recipient = AccountAddress::from_hex("0x123").unwrap();
637 let payload = InputEntryFunctionData::new("0x1::aptos_account::transfer")
638 .arg(recipient)
639 .arg(1_000_000u64)
640 .build()
641 .unwrap();
642
643 match payload {
644 TransactionPayload::EntryFunction(ef) => {
645 assert_eq!(ef.function, "transfer");
646 assert_eq!(ef.module.name.as_str(), "aptos_account");
647 assert!(ef.type_args.is_empty());
648 assert_eq!(ef.args.len(), 2);
649 }
650 _ => panic!("Expected EntryFunction"),
651 }
652 }
653
654 #[test]
655 fn test_with_type_args() {
656 let payload = InputEntryFunctionData::new("0x1::coin::transfer")
657 .type_arg("0x1::aptos_coin::AptosCoin")
658 .arg(AccountAddress::ONE)
659 .arg(1000u64)
660 .build()
661 .unwrap();
662
663 match payload {
664 TransactionPayload::EntryFunction(ef) => {
665 assert_eq!(ef.function, "transfer");
666 assert_eq!(ef.type_args.len(), 1);
667 }
668 _ => panic!("Expected EntryFunction"),
669 }
670 }
671
672 #[test]
673 fn test_invalid_function_id() {
674 let result = InputEntryFunctionData::new("invalid").arg(42u64).build();
675
676 assert!(result.is_err());
677 }
678
679 #[test]
680 fn test_invalid_type_arg() {
681 let result = InputEntryFunctionData::new("0x1::coin::transfer")
682 .type_arg("not a type")
683 .arg(AccountAddress::ONE)
684 .arg(1000u64)
685 .build();
686
687 assert!(result.is_err());
688 }
689
690 #[test]
691 fn test_transfer_apt_helper() {
692 let recipient = AccountAddress::from_hex("0x456").unwrap();
693 let payload = InputEntryFunctionData::transfer_apt(recipient, 5_000_000).unwrap();
694
695 match payload {
696 TransactionPayload::EntryFunction(ef) => {
697 assert_eq!(ef.function, "transfer");
698 assert_eq!(ef.module.name.as_str(), "aptos_account");
699 }
700 _ => panic!("Expected EntryFunction"),
701 }
702 }
703
704 #[test]
705 fn test_transfer_coin_helper() {
706 let recipient = AccountAddress::from_hex("0x789").unwrap();
707 let payload =
708 InputEntryFunctionData::transfer_coin("0x1::aptos_coin::AptosCoin", recipient, 1000)
709 .unwrap();
710
711 match payload {
712 TransactionPayload::EntryFunction(ef) => {
713 assert_eq!(ef.function, "transfer");
714 assert_eq!(ef.module.name.as_str(), "coin");
715 assert_eq!(ef.type_args.len(), 1);
716 }
717 _ => panic!("Expected EntryFunction"),
718 }
719 }
720
721 #[test]
722 fn test_various_arg_types() {
723 let payload = InputEntryFunctionData::new("0x1::test::test_function")
724 .arg(42u8)
725 .arg(1000u64)
726 .arg(true)
727 .arg("hello".to_string())
728 .arg(vec![1u8, 2u8, 3u8])
729 .arg(AccountAddress::ONE)
730 .build()
731 .unwrap();
732
733 match payload {
734 TransactionPayload::EntryFunction(ef) => {
735 assert_eq!(ef.args.len(), 6);
736 }
737 _ => panic!("Expected EntryFunction"),
738 }
739 }
740
741 #[test]
742 fn test_move_u256() {
743 let val = MoveU256::from_u128(12345);
744 let bytes = aptos_bcs::to_bytes(&val).unwrap();
745 assert_eq!(bytes.len(), 32);
746 }
747
748 #[test]
749 fn test_move_some_none() {
750 let some_bytes = move_some(42u64);
751 assert_eq!(some_bytes[0], 0x01);
752
753 let none_bytes = move_none();
754 assert_eq!(none_bytes, vec![0x00]);
755 }
756
757 #[test]
758 fn test_from_parts() {
759 let module = MoveModuleId::from_str_strict("0x1::coin").unwrap();
760 let payload = InputEntryFunctionData::from_parts(module, "transfer")
761 .type_arg("0x1::aptos_coin::AptosCoin")
762 .arg(AccountAddress::ONE)
763 .arg(1000u64)
764 .build()
765 .unwrap();
766
767 match payload {
768 TransactionPayload::EntryFunction(ef) => {
769 assert_eq!(ef.function, "transfer");
770 assert_eq!(ef.module.name.as_str(), "coin");
771 }
772 _ => panic!("Expected EntryFunction"),
773 }
774 }
775
776 #[test]
777 fn test_build_entry_function() {
778 let ef = InputEntryFunctionData::new("0x1::aptos_account::transfer")
779 .arg(AccountAddress::ONE)
780 .arg(1000u64)
781 .build_entry_function()
782 .unwrap();
783
784 assert_eq!(ef.function, "transfer");
785 assert_eq!(ef.args.len(), 2);
786 }
787
788 #[test]
789 fn test_function_constants() {
790 assert_eq!(functions::APT_TRANSFER, "0x1::aptos_account::transfer");
791 assert_eq!(functions::COIN_TRANSFER, "0x1::coin::transfer");
792 }
793
794 #[test]
795 fn test_move_u256_from_u128() {
796 let val = MoveU256::from_u128(123_456_789);
797 let expected = 123_456_789_u128.to_le_bytes();
799 assert_eq!(&val.0[..16], &expected);
800 assert_eq!(&val.0[16..], &[0u8; 16]);
802 }
803
804 #[test]
805 fn test_move_u256_from_le_bytes() {
806 let bytes = [0xab; 32];
807 let val = MoveU256::from_le_bytes(bytes);
808 assert_eq!(val.0, bytes);
809 }
810
811 #[test]
812 fn test_move_u256_parse() {
813 let val = MoveU256::parse("12345678901234567890").unwrap();
814 let expected = 12_345_678_901_234_567_890_u128;
815 let mut expected_bytes = [0u8; 32];
816 expected_bytes[..16].copy_from_slice(&expected.to_le_bytes());
817 assert_eq!(val.0, expected_bytes);
818 }
819
820 #[test]
821 fn test_move_u256_parse_invalid() {
822 let result = MoveU256::parse("999999999999999999999999999999999999999999999");
824 assert!(result.is_err());
825 }
826
827 #[test]
828 fn test_move_u256_serialization() {
829 let val = MoveU256::from_u128(0x0102_0304_0506_0708);
830 let bcs = aptos_bcs::to_bytes(&val).unwrap();
831 assert_eq!(bcs.len(), 32);
833 assert_eq!(&bcs[..8], &[0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01]);
835 }
836
837 #[test]
838 fn test_move_i128_new() {
839 let val = MoveI128::new(42);
840 assert_eq!(val.0, 42);
841 }
842
843 #[test]
844 fn test_move_i128_from_i128() {
845 let val: MoveI128 = (-100i128).into();
846 assert_eq!(val.0, -100);
847 }
848
849 #[test]
850 fn test_move_i128_serialization_positive() {
851 let val = MoveI128::new(0x0102_0304_0506_0708);
852 let bcs = aptos_bcs::to_bytes(&val).unwrap();
853 assert_eq!(bcs.len(), 16);
855 assert_eq!(&bcs[..8], &[0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01]);
857 assert_eq!(&bcs[8..], &[0, 0, 0, 0, 0, 0, 0, 0]);
859 }
860
861 #[test]
862 fn test_move_i128_serialization_negative() {
863 let val = MoveI128::new(-1);
864 let bcs = aptos_bcs::to_bytes(&val).unwrap();
865 assert_eq!(bcs.len(), 16);
866 assert_eq!(bcs, vec![0xFF; 16]);
868 }
869
870 #[test]
871 fn test_move_i256_from_i128_positive() {
872 let val = MoveI256::from_i128(42);
873 let expected = 42i128.to_le_bytes();
875 assert_eq!(&val.0[..16], &expected);
876 assert_eq!(&val.0[16..], &[0u8; 16]);
878 }
879
880 #[test]
881 fn test_move_i256_from_i128_negative() {
882 let val = MoveI256::from_i128(-1);
883 assert_eq!(val.0, [0xFF; 32]);
885 }
886
887 #[test]
888 fn test_move_i256_from_le_bytes() {
889 let bytes = [0xcd; 32];
890 let val = MoveI256::from_le_bytes(bytes);
891 assert_eq!(val.0, bytes);
892 }
893
894 #[test]
895 fn test_move_i256_from_trait() {
896 let val: MoveI256 = (-100i128).into();
897 let expected = MoveI256::from_i128(-100);
898 assert_eq!(val, expected);
899 }
900
901 #[test]
902 fn test_move_i256_serialization() {
903 let val = MoveI256::from_i128(0x0102_0304_0506_0708);
904 let bcs = aptos_bcs::to_bytes(&val).unwrap();
905 assert_eq!(bcs.len(), 32);
907 assert_eq!(&bcs[..8], &[0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01]);
909 }
910
911 #[test]
912 fn test_move_i256_serialization_negative() {
913 let val = MoveI256::from_i128(-1);
914 let bcs = aptos_bcs::to_bytes(&val).unwrap();
915 assert_eq!(bcs.len(), 32);
916 assert_eq!(bcs, vec![0xFF; 32]);
918 }
919
920 #[test]
921 fn test_input_entry_function_data_new() {
922 let builder = InputEntryFunctionData::new("0x1::coin::transfer");
923 let result = builder.build();
924 assert!(result.is_ok());
926 }
927
928 #[test]
929 fn test_input_entry_function_data_invalid_function_id() {
930 let builder = InputEntryFunctionData::new("invalid");
931 let result = builder.build();
932 assert!(result.is_err());
933 assert!(
934 result
935 .unwrap_err()
936 .to_string()
937 .contains("Invalid function ID")
938 );
939 }
940
941 #[test]
942 fn test_input_entry_function_data_type_arg() {
943 let builder = InputEntryFunctionData::new("0x1::coin::transfer")
944 .type_arg("0x1::aptos_coin::AptosCoin");
945 let result = builder.build();
946 assert!(result.is_ok());
947 }
948
949 #[test]
950 fn test_input_entry_function_data_invalid_type_arg() {
951 let builder =
952 InputEntryFunctionData::new("0x1::coin::transfer").type_arg("not a valid type");
953 let result = builder.build();
954 assert!(result.is_err());
955 assert!(result.unwrap_err().to_string().contains("type argument"));
956 }
957
958 #[test]
959 fn test_input_entry_function_data_type_arg_typed() {
960 use crate::types::TypeTag;
961
962 let builder =
963 InputEntryFunctionData::new("0x1::coin::transfer").type_arg_typed(TypeTag::U64);
964 let result = builder.build();
965 assert!(result.is_ok());
966 }
967
968 #[test]
969 fn test_input_entry_function_data_type_args() {
970 let builder = InputEntryFunctionData::new("0x1::coin::transfer").type_args(["u64", "u128"]);
971 let result = builder.build();
972 assert!(result.is_ok());
973 }
974
975 #[test]
976 fn test_input_entry_function_data_type_args_typed() {
977 use crate::types::TypeTag;
978
979 let builder = InputEntryFunctionData::new("0x1::coin::transfer")
980 .type_args_typed([TypeTag::U64, TypeTag::Bool]);
981 let result = builder.build();
982 assert!(result.is_ok());
983 }
984
985 #[test]
986 fn test_input_entry_function_data_arg() {
987 let builder = InputEntryFunctionData::new("0x1::coin::transfer")
988 .arg(42u64)
989 .arg(true)
990 .arg("hello".to_string());
991 let result = builder.build();
992 assert!(result.is_ok());
993 }
994
995 #[test]
996 fn test_input_entry_function_data_arg_raw() {
997 let raw_bytes = vec![0x01, 0x02, 0x03];
998 let builder = InputEntryFunctionData::new("0x1::coin::transfer").arg_raw(raw_bytes);
999 let result = builder.build();
1000 assert!(result.is_ok());
1001 }
1002
1003 #[test]
1004 fn test_input_entry_function_data_args() {
1005 let builder = InputEntryFunctionData::new("0x1::coin::transfer").args([1u64, 2u64, 3u64]);
1006 let result = builder.build();
1007 assert!(result.is_ok());
1008 }
1009
1010 #[test]
1011 fn test_input_entry_function_data_transfer_apt() {
1012 use crate::types::AccountAddress;
1013
1014 let recipient = AccountAddress::from_hex("0x123").unwrap();
1015 let result = InputEntryFunctionData::transfer_apt(recipient, 1000);
1016 assert!(result.is_ok());
1017 }
1018
1019 #[test]
1020 fn test_input_entry_function_data_builder_debug() {
1021 let builder = InputEntryFunctionData::new("0x1::coin::transfer");
1022 let debug = format!("{builder:?}");
1023 assert!(debug.contains("InputEntryFunctionDataBuilder"));
1024 }
1025
1026 #[test]
1027 fn test_input_entry_function_data_builder_clone() {
1028 let builder = InputEntryFunctionData::new("0x1::coin::transfer").arg(42u64);
1029 let cloned = builder.clone();
1030 assert!(cloned.build().is_ok());
1031 }
1032
1033 #[test]
1034 fn test_move_u256_debug() {
1035 let val = MoveU256::from_u128(123_456_789);
1036 let debug = format!("{val:?}");
1037 assert!(debug.contains("MoveU256"));
1038 }
1039
1040 #[test]
1041 fn test_move_i128_debug() {
1042 let val = MoveI128::new(-42);
1043 let debug = format!("{val:?}");
1044 assert!(debug.contains("MoveI128"));
1045 }
1046
1047 #[test]
1048 fn test_move_i256_debug() {
1049 let val = MoveI256::from_i128(-42);
1050 let debug = format!("{val:?}");
1051 assert!(debug.contains("MoveI256"));
1052 }
1053
1054 #[test]
1055 fn test_move_u256_equality() {
1056 let val1 = MoveU256::from_u128(100);
1057 let val2 = MoveU256::from_u128(100);
1058 let val3 = MoveU256::from_u128(200);
1059 assert_eq!(val1, val2);
1060 assert_ne!(val1, val3);
1061 }
1062
1063 #[test]
1064 fn test_move_i256_equality() {
1065 let val1 = MoveI256::from_i128(-50);
1066 let val2 = MoveI256::from_i128(-50);
1067 let val3 = MoveI256::from_i128(50);
1068 assert_eq!(val1, val2);
1069 assert_ne!(val1, val3);
1070 }
1071
1072 #[test]
1073 fn test_move_u256_clone() {
1074 let val1 = MoveU256::from_u128(999);
1075 let val2 = val1;
1076 assert_eq!(val1, val2);
1077 }
1078
1079 #[test]
1080 fn test_move_i256_clone() {
1081 let val1 = MoveI256::from_i128(-999);
1082 let val2 = val1;
1083 assert_eq!(val1, val2);
1084 }
1085}