11use crate :: cbor:: { cbor_array, cbor_map} ;
22use crate :: error:: { URError , URResult } ;
3- use crate :: registry_types:: { RegistryType , AVAX_SIGN_REQUEST , UUID , CRYPTO_KEYPATH } ;
3+ use crate :: registry_types:: { RegistryType , AVAX_SIGN_REQUEST , UUID , CRYPTO_KEYPATH , AVAX_UTXO } ;
44use crate :: crypto_key_path:: CryptoKeyPath ;
55use crate :: traits:: { From as FromCbor , RegistryItem , To } ;
66use crate :: types:: { Bytes , Fingerprint } ;
7+ use super :: avax_utxo:: AvaxUtxo ;
78use alloc:: string:: { String , ToString } ;
89use alloc:: vec:: Vec ;
910use minicbor:: data:: { Int , Tag } ;
@@ -13,24 +14,28 @@ use minicbor::{Decoder, Encoder};
1314const REQUEST_ID : u8 = 1 ;
1415const SIGN_DATA : u8 = 2 ;
1516const DERIVATION_PATH : u8 = 3 ;
17+ const UTXOS : u8 = 4 ;
1618
1719#[ derive( Debug , Clone , Default ) ]
1820pub struct AvaxSignRequest {
1921 request_id : Bytes ,
2022 sign_data : Bytes ,
21- derivation_path : CryptoKeyPath ,
23+ derivation_path : Vec < CryptoKeyPath > ,
24+ utxos : Vec < AvaxUtxo > ,
2225}
2326
2427impl AvaxSignRequest {
2528 pub fn new (
2629 request_id : Bytes ,
2730 sign_data : Bytes ,
28- derivation_path : CryptoKeyPath ,
31+ derivation_path : Vec < CryptoKeyPath > ,
32+ utxos : Vec < AvaxUtxo > ,
2933 ) -> Self {
3034 AvaxSignRequest {
3135 request_id,
3236 sign_data,
3337 derivation_path,
38+ utxos : utxos,
3439 }
3540 }
3641
@@ -50,13 +55,21 @@ impl AvaxSignRequest {
5055 self . sign_data = data;
5156 }
5257
53- pub fn get_derivation_path ( & self ) -> CryptoKeyPath {
58+ pub fn get_derivation_path ( & self ) -> Vec < CryptoKeyPath > {
5459 self . derivation_path . clone ( )
5560 }
5661
57- pub fn set_derivation_path ( & mut self , derivation_path : CryptoKeyPath ) {
62+ pub fn set_derivation_path ( & mut self , derivation_path : Vec < CryptoKeyPath > ) {
5863 self . derivation_path = derivation_path;
5964 }
65+
66+ pub fn get_utxos ( & self ) -> Vec < AvaxUtxo > {
67+ self . utxos . clone ( )
68+ }
69+
70+ pub fn set_utxos ( & mut self , utxos : Vec < AvaxUtxo > ) {
71+ self . utxos = utxos;
72+ }
6073}
6174
6275impl RegistryItem for AvaxSignRequest {
@@ -71,21 +84,43 @@ impl<C> minicbor::Encode<C> for AvaxSignRequest {
7184 e : & mut Encoder < W > ,
7285 _ctx : & mut C ,
7386 ) -> Result < ( ) , minicbor:: encode:: Error < W :: Error > > {
74- e. map ( 3 ) ?;
87+ let utxos = self . get_utxos ( ) ;
88+ let map_size = if utxos. is_empty ( ) { 3 } else { 4 } ;
89+
90+ e. map ( map_size) ?;
7591 e. int ( Int :: from ( REQUEST_ID ) ) ?
7692 . tag ( Tag :: Unassigned ( UUID . get_tag ( ) ) ) ?
7793 . bytes ( & self . request_id ) ?;
7894 e. int ( Int :: from ( SIGN_DATA ) ) ?. bytes ( & self . sign_data ) ?;
79- e. int ( Int :: from ( DERIVATION_PATH ) ) ?;
80- e. tag ( Tag :: Unassigned ( CRYPTO_KEYPATH . get_tag ( ) ) ) ?;
81- CryptoKeyPath :: encode ( & self . derivation_path , e, _ctx) ?;
95+
96+ let key_derivation_paths = self . get_derivation_path ( ) ;
97+ if key_derivation_paths. is_empty ( ) {
98+ return Err ( minicbor:: encode:: Error :: message (
99+ "key derivation paths is invalid" ,
100+ ) ) ;
101+ }
102+
103+ e. int ( Int :: from ( DERIVATION_PATH ) ) ?. array ( key_derivation_paths. len ( ) as u64 ) ?;
104+ for path in key_derivation_paths {
105+ e. tag ( Tag :: Unassigned ( CRYPTO_KEYPATH . get_tag ( ) ) ) ?;
106+ CryptoKeyPath :: encode ( & path, e, _ctx) ?;
107+ }
108+
109+ if !utxos. is_empty ( ) {
110+ e. int ( Int :: from ( UTXOS ) ) ?
111+ . array ( utxos. len ( ) as u64 ) ?;
112+ for utxo in utxos {
113+ e. tag ( Tag :: Unassigned ( AvaxUtxo :: get_registry_type ( ) . get_tag ( ) ) ) ?;
114+ AvaxUtxo :: encode ( & utxo, e, _ctx) ?;
115+ }
116+ }
82117
83118 Ok ( ( ) )
84119 }
85120}
86121
87122impl < ' b , C > minicbor:: Decode < ' b , C > for AvaxSignRequest {
88- fn decode ( d : & mut Decoder < ' b > , _ctx : & mut C ) -> Result < Self , minicbor:: decode:: Error > {
123+ fn decode ( d : & mut Decoder < ' b > , ctx : & mut C ) -> Result < Self , minicbor:: decode:: Error > {
89124 let mut result = AvaxSignRequest :: default ( ) ;
90125
91126 cbor_map ( d, & mut result, |key, obj, d| {
@@ -100,8 +135,36 @@ impl<'b, C> minicbor::Decode<'b, C> for AvaxSignRequest {
100135 obj. sign_data = d. bytes ( ) ?. to_vec ( ) ;
101136 }
102137 DERIVATION_PATH => {
103- d. tag ( ) ?;
104- obj. derivation_path = CryptoKeyPath :: decode ( d, _ctx) ?;
138+ cbor_array (
139+ d,
140+ & mut obj. derivation_path ,
141+ |_key, obj, d| {
142+ let tag = d. tag ( ) ?;
143+ if !tag. eq ( & Tag :: Unassigned (
144+ CryptoKeyPath :: get_registry_type ( ) . get_tag ( ) ,
145+ ) ) {
146+ return Err ( minicbor:: decode:: Error :: message (
147+ "CryptoKeyPath tag is invalid" ,
148+ ) ) ;
149+ }
150+ obj. push ( CryptoKeyPath :: decode ( d, ctx) ?) ;
151+ Ok ( ( ) )
152+ } ,
153+ ) ?;
154+ }
155+ UTXOS => {
156+ cbor_array ( d, & mut obj. utxos , |_key, obj, d| {
157+ let tag = d. tag ( ) ?;
158+ if !tag. eq ( & Tag :: Unassigned (
159+ AvaxUtxo :: get_registry_type ( ) . get_tag ( ) ,
160+ ) ) {
161+ return Err ( minicbor:: decode:: Error :: message (
162+ "AvaxUtxo tag is invalid" ,
163+ ) ) ;
164+ }
165+ obj. push ( AvaxUtxo :: decode ( d, ctx) ?) ;
166+ Ok ( ( ) )
167+ } ) ?;
105168 }
106169 _ => { }
107170 }
@@ -139,19 +202,21 @@ mod tests {
139202 let components = vec ! [
140203 PathComponent :: new( Some ( 44 ) , true ) . unwrap( ) ,
141204 PathComponent :: new( Some ( 9000 ) , true ) . unwrap( ) ,
142- PathComponent :: new( Some ( 1 ) , true ) . unwrap( ) ,
205+ PathComponent :: new( Some ( 0 ) , true ) . unwrap( ) ,
143206 PathComponent :: new( Some ( 0 ) , false ) . unwrap( ) ,
144207 PathComponent :: new( Some ( 0 ) , false ) . unwrap( ) ,
145208 ] ;
209+ let utxos = vec ! [ ] ;
146210 let unsigned_data = AvaxSignRequest {
147211 request_id : [ 12 , 34 , 56 , 78 ] . to_vec ( ) ,
148- sign_data : Vec :: from_hex ( "000000000022000000050000000000000000000000000000000000000000000000000000000000000000000000023d9bdac0ed1d761330cf680efdeb1a42159eb387d6d2950c96f7d28f61bbe2aa0000000700000000000f42400000000000000000000000010000000132336f8715dd313a426155cccc15ba27c3033dae3d9bdac0ed1d761330cf680efdeb1a42159eb387d6d2950c96f7d28f61bbe2aa00000007000000004d58ade90000000000000000000000010000000132336f8715dd313a426155cccc15ba27c3033dae00000001410b47f7c7aa13f88122be58735c5e985edc65d86fb0baf0b016359c22253d75000000013d9bdac0ed1d761330cf680efdeb1a42159eb387d6d2950c96f7d28f61bbe2aa00000005000000004d680464000000010000000000000000 " )
212+ sign_data : Vec :: from_hex ( "0000000000220000000100000000000000000000000000000000000000000000000000000000000000000000000221e67317cbc4be2aeb00677ad6462778a8f52274b9d605df2591b23027a87dff000000070000000000007d4c00000000000000000000000100000001b5e66be5c7093d1114d74940333c0c45f81092c521e67317cbc4be2aeb00677ad6462778a8f52274b9d605df2591b23027a87dff000000070000000002ed658f00000000000000000000000100000001b5e66be5c7093d1114d74940333c0c45f81092c500000001918cf421e834d4d7031175ac9605ba292ee04a17beb4fb81f8557969b4651b860000000121e67317cbc4be2aeb00677ad6462778a8f52274b9d605df2591b23027a87dff000000050000000002edf716000000010000000000000000 " )
149213 . unwrap ( ) ,
150- derivation_path : CryptoKeyPath :: new (
214+ derivation_path : vec ! [ CryptoKeyPath :: new(
151215 components,
152216 Some ( [ 45 , 11 , 218 , 188 ] ) ,
153217 None ,
154- ) ,
218+ ) ] ,
219+ utxos
155220 } ;
156221 let result: Vec < u8 > = unsigned_data. try_into ( ) . unwrap ( ) ;
157222 println ! ( "result = {:?}" , hex:: encode( & result) ) ;
@@ -164,7 +229,7 @@ mod tests {
164229 let ur_string = "ur:avax-sign-request/otadtpdafybncpetglaohkaddmaeaeaeaeaecpaeaeaeahaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaofsndtnrtwecakobwdytkisbazcwmcyfwbznnqdlttbtdmdbnmtyltdmyhsrkvopkaeaeaeataeaeaeaeaebsfwfzaeaeaeaeaeaeaeaeaeaeaeadaeaeaeadeyeojlltbzutehftfwhsgosfsfbzrddisraxfsplfsndtnrtwecakobwdytkisbazcwmcyfwbznnqdlttbtdmdbnmtyltdmyhsrkvopkaeaeaeataeaeaeaegthdpmwlaeaeaeaeaeaeaeaeaeaeaeadaeaeaeadeyeojlltbzutehftfwhsgosfsfbzrddisraxfsplaeaeaeadfpbdflylstpkbwyalycprnhdjkhhhymkhyuoihtpjlpfrdwtpfcmecnscpdafskpaeaeaeadfsndtnrtwecakobwdytkisbazcwmcyfwbznnqdlttbtdmdbnmtyltdmyhsrkvopkaeaeaeahaeaeaeaegtisaaieaeaeaeadaeaeaeaeaeaeaeaeaxtaaddyoeadlecsdwykcfcndeykaeykaewkaewkaocybggdrprfknlulrbk" ;
165230
166231 let bytes =
167- Vec :: from_hex ( "a501d825440c22384e0258de00000000000000000001ed5f38341e436e5d46e2bb00b45d62ae97d1b050c64bc634ae10626739e35c4b0000000121e67317cbc4be2aeb00677ad6462778a8f52274b9d605df2591b23027a87dff00000007000000000089544000000000000000000000000100000001512e7191685398f00663e12197a3d8f6012d9ea300000001db720ad6707915cc4751fb7e5491a3af74e127a1d81817abe9438590c0833fe10000000021e67317cbc4be2aeb00677ad6462778a8f52274b9d605df2591b23027a87dff000000050000000000989680000000010000000000000000031a0102030406786f7870756236445872797a384b6437586368745876446e6b6a61726138337368474a4838756275374b5a684868506670344c3173687644455969465a6d3332454b486e796f34627661346778586a61624647715937664e7338476764346b68597a326f4e73324b594c663536613947580706" )
232+ Vec :: from_hex ( "a401d82550d797b45aef4b483cb106506e288b2c77025903960000000000220000000100000000000000000000000000000000000000000000000000000000000000000000000221e67317cbc4be2aeb00677ad6462778a8f52274b9d605df2591b23027a87dff00000007000000000031cb3a00000000000000000000000100000001b5e66be5c7093d1114d74940333c0c45f81092c521e67317cbc4be2aeb00677ad6462778a8f52274b9d605df2591b23027a87dff000000070000000005dabac900000000000000000000000100000001b5e66be5c7093d1114d74940333c0c45f81092c500000008120d0def706b8b759935b8ea9727662aafa5381e598a074daddc82492549cd760000000021e67317cbc4be2aeb00677ad6462778a8f52274b9d605df2591b23027a87dff00000005000000000046239d0000000100000000174d1a9b28e1d4d518f1999d4f8ac422b8a3a4755001f5965e8d05c93359feb10000000021e67317cbc4be2aeb00677ad6462778a8f52274b9d605df2591b23027a87dff00000005000000000131021c0000000100000000174d1a9b28e1d4d518f1999d4f8ac422b8a3a4755001f5965e8d05c93359feb10000000121e67317cbc4be2aeb00677ad6462778a8f52274b9d605df2591b23027a87dff00000005000000000176b6a5000000010000000065a3b1de10620296debfa01aa953e45ddd19d2c39e3dacb9a92e6a85ca8a309c0000000021e67317cbc4be2aeb00677ad6462778a8f52274b9d605df2591b23027a87dff00000005000000000098968000000001000000006f6522ae52b0231076dc63ff95f7ea22e2fd80943e37235302c7ee32afce4cd60000000021e67317cbc4be2aeb00677ad6462778a8f52274b9d605df2591b23027a87dff0000000500000000009896800000000100000000845649c3d1a630d8b466f7b727f6577cb4a17864699e6de756e484b81d84cd2a0000000021e67317cbc4be2aeb00677ad6462778a8f52274b9d605df2591b23027a87dff0000000500000000006c2b440000000100000000d1e6480c1825197e2ec293a60bacdc7f60bfba2f3cc5383855180b45d595a7030000000021e67317cbc4be2aeb00677ad6462778a8f52274b9d605df2591b23027a87dff0000000500000000007a12000000000100000000f59b9a175ebe4ccd8de5dcfc6a26870414f30c696cce19283f30145624b445b70000000021e67317cbc4be2aeb00677ad6462778a8f52274b9d605df2591b23027a87dff00000005000000000107a4930000000100000000000000000382d90130a2018a182cf5192328f500f500f400f4021a2d0bdabcd90130a2018a182cf5192328f500f500f401f4021a2d0bdabc0480" )
168233 . unwrap ( ) ;
169234 let data = AvaxSignRequest :: try_from ( bytes) . unwrap ( ) ;
170235 assert_eq ! (
0 commit comments