22 super :: { CacaoError , Version } ,
33 crate :: auth:: did:: { extract_did_data, DID_METHOD_KEY } ,
44 serde:: { Deserialize , Serialize } ,
5+ url:: Url ,
56} ;
67
78#[ derive( Clone , Debug , PartialEq , Eq , Deserialize , Serialize , Hash ) ]
@@ -24,6 +25,7 @@ impl Payload {
2425 const ISS_POSITION_OF_ADDRESS : usize = 4 ;
2526 const ISS_POSITION_OF_NAMESPACE : usize = 2 ;
2627 const ISS_POSITION_OF_REFERENCE : usize = 3 ;
28+ pub const WALLETCONNECT_IDENTITY_KEY : & ' static str = "walletconnect_identity_key" ;
2729
2830 /// TODO: write valdation
2931 pub fn validate ( & self ) -> Result < ( ) , CacaoError > {
@@ -77,21 +79,141 @@ impl Payload {
7779 . or_else ( |_| self . identity_key_from_resources ( ) )
7880 }
7981
82+ fn extract_did_key ( did_key : & str ) -> Result < String , CacaoError > {
83+ extract_did_data ( did_key, DID_METHOD_KEY )
84+ . map_err ( |_| CacaoError :: PayloadIdentityKey )
85+ . map ( |data| data. to_owned ( ) )
86+ }
87+
8088 fn identity_key_from_resources ( & self ) -> Result < String , CacaoError > {
8189 let resources = self
8290 . resources
8391 . as_ref ( )
8492 . ok_or ( CacaoError :: PayloadResources ) ?;
8593 let did_key = resources. first ( ) . ok_or ( CacaoError :: PayloadIdentityKey ) ?;
8694
87- extract_did_data ( did_key, DID_METHOD_KEY )
88- . map ( |data| data. to_string ( ) )
89- . map_err ( |_| CacaoError :: PayloadIdentityKey )
95+ Self :: extract_did_key ( did_key)
9096 }
9197
9298 fn identity_key_from_audience ( & self ) -> Result < String , CacaoError > {
93- extract_did_data ( & self . aud , DID_METHOD_KEY )
94- . map ( |data| data. to_string ( ) )
99+ self . identity_key_from_audience_url ( )
100+ . or_else ( |_| self . identity_key_from_audience_did_key ( ) )
101+ }
102+
103+ fn identity_key_from_audience_did_key ( & self ) -> Result < String , CacaoError > {
104+ Self :: extract_did_key ( & self . aud )
105+ }
106+
107+ fn identity_key_from_audience_url ( & self ) -> Result < String , CacaoError > {
108+ self . aud
109+ . parse :: < Url > ( )
95110 . map_err ( |_| CacaoError :: PayloadIdentityKey )
111+ . and_then ( |url| {
112+ url. query_pairs ( )
113+ . find ( |( key, _) | key == Self :: WALLETCONNECT_IDENTITY_KEY )
114+ . ok_or ( CacaoError :: PayloadIdentityKey )
115+ . and_then ( |( _, value) | Self :: extract_did_key ( & value) )
116+ } )
117+ }
118+ }
119+
120+ #[ cfg( test) ]
121+ mod tests {
122+ use super :: * ;
123+
124+ #[ test]
125+ fn identity_key_from_resources ( ) {
126+ assert_eq ! (
127+ Payload {
128+ domain: "example.com" . to_owned( ) ,
129+ iss: "did:pkh:eip155:1:0xdFe7d0E324ed017a74aE311E9236E6CaDB24176b" . to_owned( ) ,
130+ statement: None ,
131+ aud: "" . to_owned( ) ,
132+ version: Version :: V1 ,
133+ nonce: "" . to_owned( ) ,
134+ iat: "2023-09-07T11:04:23+02:00" . to_owned( ) ,
135+ exp: None ,
136+ nbf: None ,
137+ request_id: None ,
138+ resources: Some ( vec![
139+ "did:key:z6MkvjNoiz9AXGH1igzrtB54US5hE9bZPQm1ryKGkCLwWht7" . to_owned( ) ,
140+ ] ) ,
141+ }
142+ . identity_key( )
143+ . unwrap( ) ,
144+ "z6MkvjNoiz9AXGH1igzrtB54US5hE9bZPQm1ryKGkCLwWht7"
145+ ) ;
146+ }
147+
148+ #[ test]
149+ fn identity_key_from_aud ( ) {
150+ assert_eq ! (
151+ Payload {
152+ domain: "example.com" . to_owned( ) ,
153+ iss: "did:pkh:eip155:1:0xdFe7d0E324ed017a74aE311E9236E6CaDB24176b" . to_owned( ) ,
154+ statement: None ,
155+ aud: "did:key:z6MkvjNoiz9AXGH1igzrtB54US5hE9bZPQm1ryKGkCLwWht7" . to_owned( ) ,
156+ version: Version :: V1 ,
157+ nonce: "" . to_owned( ) ,
158+ iat: "2023-09-07T11:04:23+02:00" . to_owned( ) ,
159+ exp: None ,
160+ nbf: None ,
161+ request_id: None ,
162+ resources: Some ( vec![
163+ "did:key:z6MkvjNoiz9AXGH1igzrtB54US5hE9bZPQm1ryKGkCLwWht8" . to_owned( ) ,
164+ ] ) ,
165+ }
166+ . identity_key( )
167+ . unwrap( ) ,
168+ "z6MkvjNoiz9AXGH1igzrtB54US5hE9bZPQm1ryKGkCLwWht7"
169+ ) ;
170+ }
171+
172+ #[ test]
173+ fn identity_key_from_aud_url ( ) {
174+ assert_eq ! (
175+ Payload {
176+ domain: "example.com" . to_owned( ) ,
177+ iss: "did:pkh:eip155:1:0xdFe7d0E324ed017a74aE311E9236E6CaDB24176b" . to_owned( ) ,
178+ statement: None ,
179+ aud: "https://example.com?walletconnect_identity_key=did:key:z6MkvjNoiz9AXGH1igzrtB54US5hE9bZPQm1ryKGkCLwWht7" . to_owned( ) ,
180+ version: Version :: V1 ,
181+ nonce: "" . to_owned( ) ,
182+ iat: "2023-09-07T11:04:23+02:00" . to_owned( ) ,
183+ exp: None ,
184+ nbf: None ,
185+ request_id: None ,
186+ resources: Some ( vec![
187+ "did:key:z6MkvjNoiz9AXGH1igzrtB54US5hE9bZPQm1ryKGkCLwWht8" . to_owned( ) ,
188+ ] ) ,
189+ }
190+ . identity_key( )
191+ . unwrap( ) ,
192+ "z6MkvjNoiz9AXGH1igzrtB54US5hE9bZPQm1ryKGkCLwWht7"
193+ ) ;
194+ }
195+
196+ #[ test]
197+ fn identity_key_from_aud_url_encoded ( ) {
198+ assert_eq ! (
199+ Payload {
200+ domain: "example.com" . to_owned( ) ,
201+ iss: "did:pkh:eip155:1:0xdFe7d0E324ed017a74aE311E9236E6CaDB24176b" . to_owned( ) ,
202+ statement: None ,
203+ aud: "https://example.com?walletconnect_identity_key=did%3Akey%3Az6MkvjNoiz9AXGH1igzrtB54US5hE9bZPQm1ryKGkCLwWht7" . to_owned( ) ,
204+ version: Version :: V1 ,
205+ nonce: "" . to_owned( ) ,
206+ iat: "2023-09-07T11:04:23+02:00" . to_owned( ) ,
207+ exp: None ,
208+ nbf: None ,
209+ request_id: None ,
210+ resources: Some ( vec![
211+ "did:key:z6MkvjNoiz9AXGH1igzrtB54US5hE9bZPQm1ryKGkCLwWht8" . to_owned( ) ,
212+ ] ) ,
213+ }
214+ . identity_key( )
215+ . unwrap( ) ,
216+ "z6MkvjNoiz9AXGH1igzrtB54US5hE9bZPQm1ryKGkCLwWht7"
217+ ) ;
96218 }
97219}
0 commit comments