@@ -648,6 +648,12 @@ impl PlutusData {
648648 Self :: new_constr_plutus_data ( & ConstrPlutusData :: new ( alternative, & PlutusList :: new ( ) ) )
649649 }
650650
651+ pub fn new_single_value_constr_plutus_data ( alternative : & BigNum , plutus_data : & PlutusData ) -> Self {
652+ let mut list = PlutusList :: new ( ) ;
653+ list. add ( plutus_data) ;
654+ Self :: new_constr_plutus_data ( & ConstrPlutusData :: new ( alternative, & list) )
655+ }
656+
651657 pub fn new_map ( map : & PlutusMap ) -> Self {
652658 Self {
653659 datum : PlutusDataEnum :: Map ( map. clone ( ) ) ,
@@ -728,6 +734,82 @@ impl PlutusData {
728734 pub fn from_json ( json : & str , schema : PlutusDatumSchema ) -> Result < PlutusData , JsError > {
729735 encode_json_str_to_plutus_datum ( json, schema)
730736 }
737+
738+ pub fn from_address ( address : & Address ) -> Result < PlutusData , JsError > {
739+ let payment_cred = match & address. 0 {
740+ AddrType :: Base ( addr) => Ok ( addr. payment_cred ( ) ) ,
741+ AddrType :: Enterprise ( addr) => Ok ( addr. payment_cred ( ) ) ,
742+ AddrType :: Ptr ( addr) => Ok ( addr. payment_cred ( ) ) ,
743+ AddrType :: Reward ( addr) => Ok ( addr. payment_cred ( ) ) ,
744+ AddrType :: Byron ( _) =>
745+ Err ( JsError :: from_str ( "Cannot convert Byron address to PlutusData" ) ) ,
746+ } ?;
747+
748+ let staking_data = match & address. 0 {
749+ AddrType :: Base ( addr) => {
750+ let staking_bytes_data =
751+ PlutusData :: from_stake_credential ( & addr. stake_cred ( ) ) ?;
752+ Some ( PlutusData :: new_single_value_constr_plutus_data (
753+ & BigNum :: from ( 0u32 ) ,
754+ & staking_bytes_data,
755+ ) )
756+ }
757+ _ => None ,
758+ } ;
759+
760+ let pointer_data = match & address. 0 {
761+ AddrType :: Ptr ( addr) =>
762+ Some ( PlutusData :: from_pointer ( & addr. stake_pointer ( ) ) ?) ,
763+ _ => None ,
764+ } ;
765+
766+ let payment_data = PlutusData :: from_stake_credential ( & payment_cred) ?;
767+ let staking_optional_data = match ( staking_data, pointer_data) {
768+ ( Some ( _) , Some ( _) ) =>
769+ Err ( JsError :: from_str ( "Address can't have both staking and pointer data" ) ) ,
770+ ( Some ( staking_data) , None ) => Ok ( Some ( staking_data) ) ,
771+ ( None , Some ( pointer_data) ) => Ok ( Some ( pointer_data) ) ,
772+ ( None , None ) => Ok ( None )
773+ } ?;
774+
775+ let mut data_list = PlutusList :: new ( ) ;
776+ data_list. add ( & payment_data) ;
777+ if let Some ( staking_optional_data) = staking_optional_data {
778+ data_list. add (
779+ & PlutusData :: new_single_value_constr_plutus_data (
780+ & BigNum :: from ( 0u32 ) , & staking_optional_data) ) ;
781+ } else {
782+ data_list. add ( & PlutusData :: new_empty_constr_plutus_data (
783+ & BigNum :: from ( 1u32 ) ) ) ;
784+ }
785+
786+
787+ Ok ( PlutusData :: new_constr_plutus_data ( & ConstrPlutusData :: new (
788+ & BigNum :: from ( 0u32 ) ,
789+ & data_list,
790+ ) ) )
791+ }
792+
793+ fn from_stake_credential ( stake_credential : & StakeCredential ) -> Result < PlutusData , JsError > {
794+ let ( bytes_plutus_data, index) = match & stake_credential. 0 {
795+ StakeCredType :: Key ( key_hash) =>
796+ ( PlutusData :: new_bytes ( key_hash. to_bytes ( ) . to_vec ( ) ) , BigNum :: from ( 0u32 ) ) ,
797+ StakeCredType :: Script ( script_hash) =>
798+ ( PlutusData :: new_bytes ( script_hash. to_bytes ( ) . to_vec ( ) ) , BigNum :: from ( 1u32 ) ) ,
799+ } ;
800+
801+ Ok ( PlutusData :: new_single_value_constr_plutus_data ( & index, & bytes_plutus_data) )
802+ }
803+
804+ fn from_pointer ( pointer : & Pointer ) -> Result < PlutusData , JsError > {
805+ let mut data_list = PlutusList :: new ( ) ;
806+ data_list. add ( & PlutusData :: new_integer ( & pointer. slot_bignum ( ) . into ( ) ) ) ;
807+ data_list. add ( & PlutusData :: new_integer ( & pointer. tx_index_bignum ( ) . into ( ) ) ) ;
808+ data_list. add ( & PlutusData :: new_integer ( & pointer. cert_index_bignum ( ) . into ( ) ) ) ;
809+
810+ Ok ( PlutusData :: new_constr_plutus_data (
811+ & ConstrPlutusData :: new ( & BigNum :: from ( 1u32 ) , & data_list) ) )
812+ }
731813}
732814
733815//TODO: replace this by cardano-node schemas
@@ -2443,4 +2525,58 @@ mod tests {
24432525 ) ;
24442526 assert_eq ! ( hex:: encode( hash. to_bytes( ) ) , "0a076247a05aacbecf72ea15b94e3d0331b21295a08d9ab7b8675c13840563a6" ) ;
24452527 }
2528+
2529+ #[ test]
2530+ fn datum_from_enterprise_key_address ( ) {
2531+ let address = Address :: from_bech32 ( "addr1vxy2c673nsdp0mvgq5d3tpjndngucsytug00k7k6xwlx4lg6dspk5" ) . unwrap ( ) ;
2532+ let datum = PlutusData :: from_address ( & address) . unwrap ( ) ;
2533+ let orig_datum = PlutusData :: from_json ( "{\" constructor\" : 0, \" fields\" : [{\" constructor\" : 0, \" fields\" : [{\" bytes\" : \" 88ac6bd19c1a17ed88051b1586536cd1cc408be21efb7ada33be6afd\" }]}, {\" constructor\" : 1, \" fields\" : []}]}" ,
2534+ PlutusDatumSchema :: DetailedSchema ) . unwrap ( ) ;
2535+ assert_eq ! ( datum, orig_datum) ;
2536+ }
2537+
2538+ #[ test]
2539+ fn datum_from_enterprise_script_address ( ) {
2540+ let address = Address :: from_bech32 ( "addr1w8wrk560wcsldjpnqjamn8s0gn9pdrplpyetrdfpacqrpfs3xezd8" ) . unwrap ( ) ;
2541+ let datum = PlutusData :: from_address ( & address) . unwrap ( ) ;
2542+ let orig_datum = PlutusData :: from_json ( "{\" constructor\" : 0, \" fields\" : [{\" constructor\" : 1, \" fields\" : [{\" bytes\" : \" dc3b534f7621f6c83304bbb99e0f44ca168c3f0932b1b521ee0030a6\" }]}, {\" constructor\" : 1, \" fields\" : []}]}" ,
2543+ PlutusDatumSchema :: DetailedSchema ) . unwrap ( ) ;
2544+ assert_eq ! ( datum, orig_datum) ;
2545+ }
2546+
2547+ #[ test]
2548+ fn datum_from_base_key_key_address ( ) {
2549+ let address = Address :: from_bech32 ( "addr1qxy2c673nsdp0mvgq5d3tpjndngucsytug00k7k6xwlx4lvg434ar8q6zlkcspgmzkr9xmx3e3qghcs7ldad5va7dt7s5efyer" ) . unwrap ( ) ;
2550+ let datum = PlutusData :: from_address ( & address) . unwrap ( ) ;
2551+ let orig_datum = PlutusData :: from_json ( "{\" constructor\" : 0, \" fields\" : [{\" constructor\" : 0, \" fields\" : [{\" bytes\" : \" 88ac6bd19c1a17ed88051b1586536cd1cc408be21efb7ada33be6afd\" }]}, {\" constructor\" : 0, \" fields\" : [{\" constructor\" : 0, \" fields\" : [{\" constructor\" : 0, \" fields\" : [{\" bytes\" : \" 88ac6bd19c1a17ed88051b1586536cd1cc408be21efb7ada33be6afd\" }]}]}]}]}" ,
2552+ PlutusDatumSchema :: DetailedSchema ) . unwrap ( ) ;
2553+ assert_eq ! ( datum, orig_datum) ;
2554+ }
2555+
2556+ #[ test]
2557+ fn datum_from_base_script_script_address ( ) {
2558+ let address = Address :: from_bech32 ( "addr1x8wrk560wcsldjpnqjamn8s0gn9pdrplpyetrdfpacqrpfku8df57a3p7myrxp9mhx0q73x2z6xr7zfjkx6jrmsqxznqh8u5dz" ) . unwrap ( ) ;
2559+ let datum = PlutusData :: from_address ( & address) . unwrap ( ) ;
2560+ let orig_datum = PlutusData :: from_json ( "{\" constructor\" : 0, \" fields\" : [{\" constructor\" : 1, \" fields\" : [{\" bytes\" : \" dc3b534f7621f6c83304bbb99e0f44ca168c3f0932b1b521ee0030a6\" }]}, {\" constructor\" : 0, \" fields\" : [{\" constructor\" : 0, \" fields\" : [{\" constructor\" : 1, \" fields\" : [{\" bytes\" : \" dc3b534f7621f6c83304bbb99e0f44ca168c3f0932b1b521ee0030a6\" }]}]}]}]}" ,
2561+ PlutusDatumSchema :: DetailedSchema ) . unwrap ( ) ;
2562+ assert_eq ! ( datum, orig_datum) ;
2563+ }
2564+
2565+ #[ test]
2566+ fn datum_from_base_script_key_address ( ) {
2567+ let address = Address :: from_bech32 ( "addr1z8wrk560wcsldjpnqjamn8s0gn9pdrplpyetrdfpacqrpf5g434ar8q6zlkcspgmzkr9xmx3e3qghcs7ldad5va7dt7sqx2wxh" ) . unwrap ( ) ;
2568+ let datum = PlutusData :: from_address ( & address) . unwrap ( ) ;
2569+ let orig_datum = PlutusData :: from_json ( "{\" constructor\" : 0, \" fields\" : [{\" constructor\" : 1, \" fields\" : [{\" bytes\" : \" dc3b534f7621f6c83304bbb99e0f44ca168c3f0932b1b521ee0030a6\" }]}, {\" constructor\" : 0, \" fields\" : [{\" constructor\" : 0, \" fields\" : [{\" constructor\" : 0, \" fields\" : [{\" bytes\" : \" 88ac6bd19c1a17ed88051b1586536cd1cc408be21efb7ada33be6afd\" }]}]}]}]}" ,
2570+ PlutusDatumSchema :: DetailedSchema ) . unwrap ( ) ;
2571+ assert_eq ! ( datum, orig_datum) ;
2572+ }
2573+
2574+ #[ test]
2575+ fn datum_from_base_key_script_address ( ) {
2576+ let address = Address :: from_bech32 ( "addr1yxy2c673nsdp0mvgq5d3tpjndngucsytug00k7k6xwlx4lwu8df57a3p7myrxp9mhx0q73x2z6xr7zfjkx6jrmsqxznqrcl7jk" ) . unwrap ( ) ;
2577+ let datum = PlutusData :: from_address ( & address) . unwrap ( ) ;
2578+ let orig_datum = PlutusData :: from_json ( "{\" constructor\" : 0, \" fields\" : [{\" constructor\" : 0, \" fields\" : [{\" bytes\" : \" 88ac6bd19c1a17ed88051b1586536cd1cc408be21efb7ada33be6afd\" }]}, {\" constructor\" : 0, \" fields\" : [{\" constructor\" : 0, \" fields\" : [{\" constructor\" : 1, \" fields\" : [{\" bytes\" : \" dc3b534f7621f6c83304bbb99e0f44ca168c3f0932b1b521ee0030a6\" }]}]}]}]}" ,
2579+ PlutusDatumSchema :: DetailedSchema ) . unwrap ( ) ;
2580+ assert_eq ! ( datum, orig_datum) ;
2581+ }
24462582}
0 commit comments