1use crate::errors::DidSolError;
2use anchor_lang::prelude::*;
3use bitflags::bitflags;
4use itertools::Itertools;
5use num_derive::*;
6use num_traits::*;
7use std::fmt::{Display, Formatter};
8
9use crate::constants::VM_DEFAULT_FRAGMENT_NAME;
10use crate::utils::{
11 check_other_controllers, convert_secp256k1pub_key_to_address, derive_did_account,
12 derive_did_account_with_bump, eth_verify_message,
13};
14
15#[account]
16pub struct DidAccount {
17 pub version: u8,
19 pub bump: u8,
21 pub nonce: u64,
23 pub initial_verification_method: VerificationMethod,
25 pub verification_methods: Vec<VerificationMethod>,
27 pub services: Vec<Service>,
29 pub native_controllers: Vec<Pubkey>,
31 pub other_controllers: Vec<String>,
33}
34
35impl Display for DidAccount {
36 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
37 let base_58_authority_key = &self.native_controllers.first().unwrap().to_string();
38 write!(f, "did:sol:{}", base_58_authority_key)
39 }
40}
41
42impl Default for DidAccount {
43 fn default() -> Self {
44 DidAccount {
45 version: 0,
46 bump: 0,
47 nonce: 0,
48 initial_verification_method: VerificationMethod {
49 fragment: VM_DEFAULT_FRAGMENT_NAME.to_string(),
50 flags: VerificationMethodFlags::CAPABILITY_INVOCATION.bits(),
51 method_type: 0,
52 key_data: vec![],
53 },
54 verification_methods: vec![],
55 services: vec![],
56 native_controllers: vec![],
57 other_controllers: vec![],
58 }
59 }
60}
61
62impl DidAccount {
63 pub fn new(bump: u8, authority_key: &Pubkey) -> Self {
64 Self {
65 version: 0,
66 bump,
67 nonce: 0,
68 initial_verification_method: VerificationMethod::default(
69 VerificationMethodFlags::CAPABILITY_INVOCATION
70 | VerificationMethodFlags::OWNERSHIP_PROOF,
71 authority_key.to_bytes().to_vec(),
72 ),
73 verification_methods: vec![],
74 services: vec![],
75 native_controllers: vec![],
76 other_controllers: vec![],
77 }
78 }
79
80 pub fn init(&mut self, bump: u8, authority_key: &Pubkey, flags: VerificationMethodFlags) {
81 self.version = 0;
82 self.bump = bump;
83 self.nonce = 0;
84
85 self.initial_verification_method =
86 VerificationMethod::default(flags, authority_key.to_bytes().to_vec());
87 }
88
89 pub fn verification_methods(
92 &self,
93 filter_types: Option<&[VerificationMethodType]>,
94 filter_flags: Option<VerificationMethodFlags>,
95 filter_key: Option<&[u8]>,
96 filter_fragment: Option<&String>,
97 ) -> Vec<&VerificationMethod> {
98 std::iter::once(&self.initial_verification_method)
99 .chain(self.verification_methods.iter())
100 .filter(|vm| match filter_types {
101 Some(filter_types) => {
102 filter_types.contains(&VerificationMethodType::from_u8(vm.method_type).unwrap())
103 }
104 None => true,
105 })
106 .filter(|vm| match filter_flags {
107 Some(filter_flags) => VerificationMethodFlags::from_bits(vm.flags)
108 .unwrap()
109 .contains(filter_flags),
110 None => true,
111 })
112 .filter(|vm| match filter_key {
113 Some(filter_key) => vm.key_data == filter_key,
114 None => true,
115 })
116 .filter(|vm| match filter_fragment {
117 Some(filter_fragment) => vm.fragment == *filter_fragment,
118 None => true,
119 })
120 .collect()
121 }
122
123 pub fn verification_methods_mut(
127 &mut self,
128 filter_types: Option<&[VerificationMethodType]>,
129 filter_flags: Option<VerificationMethodFlags>,
130 filter_key: Option<&[u8]>,
131 filter_fragment: Option<&String>,
132 ) -> Vec<&mut VerificationMethod> {
133 std::iter::once(&mut self.initial_verification_method)
134 .chain(self.verification_methods.iter_mut())
135 .filter(|vm| match filter_types {
136 Some(filter_types) => {
137 filter_types.contains(&VerificationMethodType::from_u8(vm.method_type).unwrap())
138 }
139 None => true,
140 })
141 .filter(|vm| match filter_flags {
142 Some(filter_flags) => VerificationMethodFlags::from_bits(vm.flags)
143 .unwrap()
144 .contains(filter_flags),
145 None => true,
146 })
147 .filter(|vm| match filter_key {
148 Some(filter_key) => vm.key_data == filter_key,
149 None => true,
150 })
151 .filter(|vm| match filter_fragment {
152 Some(filter_fragment) => vm.fragment == *filter_fragment,
153 None => true,
154 })
155 .collect()
156 }
157
158 pub fn remove_verification_method(&mut self, fragment: &String) -> Result<()> {
159 if fragment == &self.initial_verification_method.fragment {
161 self.initial_verification_method.flags = 0;
162 return Ok(());
163 }
164
165 self.verification_methods
167 .iter()
168 .position(|vm| vm.fragment == *fragment)
169 .map(|index| {
170 self.verification_methods.remove(index);
171 })
172 .ok_or_else(|| error!(DidSolError::VmFragmentNotFound))
173 }
174
175 pub fn find_verification_method(
176 &mut self,
177 fragment: &String,
178 ) -> Option<&mut VerificationMethod> {
179 self.verification_methods_mut(None, None, None, Some(fragment))
180 .into_iter()
181 .next()
182 }
183
184 pub fn has_authority_verification_methods(&self) -> bool {
185 !self
186 .verification_methods(
187 Some(&VerificationMethodType::authority_types()),
188 Some(VerificationMethodFlags::CAPABILITY_INVOCATION),
189 None,
190 None,
191 )
192 .is_empty()
193 }
194
195 pub fn find_authority_constraint(
196 &self,
197 sol_authority: &Pubkey,
198 eth_message: &[u8],
199 eth_raw_signature: Option<&Secp256k1RawSignature>,
200 filter_fragment: Option<&String>,
201 ) -> Option<&VerificationMethod> {
202 let vm = self.find_authority(
204 &sol_authority.to_bytes(),
205 Some(&[VerificationMethodType::Ed25519VerificationKey2018]),
206 filter_fragment,
207 );
208 if vm.is_some() {
209 return vm;
210 }
211
212 if let Some(eth_raw_signature) = eth_raw_signature {
213 let secp256k1_pubkey = eth_verify_message(
215 eth_message,
216 self.nonce,
217 eth_raw_signature.signature,
218 eth_raw_signature.recovery_id,
219 )
220 .ok()?;
221
222 let vm = self.find_authority(
223 &secp256k1_pubkey.to_bytes(),
224 Some(&[VerificationMethodType::EcdsaSecp256k1VerificationKey2019]),
225 filter_fragment,
226 );
227 if vm.is_some() {
228 return vm;
229 }
230
231 let address = convert_secp256k1pub_key_to_address(&secp256k1_pubkey);
232 let vm = self.find_authority(
233 &address,
234 Some(&[VerificationMethodType::EcdsaSecp256k1RecoveryMethod2020]),
235 filter_fragment,
236 );
237 if vm.is_some() {
238 return vm;
239 }
240 }
241
242 None
243 }
244
245 pub fn find_authority(
246 &self,
247 key: &[u8],
248 filter_types: Option<&[VerificationMethodType]>,
249 filter_fragment: Option<&String>,
250 ) -> Option<&VerificationMethod> {
251 self.verification_methods(
253 filter_types,
254 Some(VerificationMethodFlags::CAPABILITY_INVOCATION),
255 Some(key),
256 filter_fragment,
257 )
258 .into_iter()
259 .next()
260 }
261
262 pub fn authority_key(&self) -> Pubkey {
263 Pubkey::new(self.initial_verification_method.key_data.as_slice())
264 }
265
266 pub fn is_directly_controlled_by(&self, other: &DidAccount) -> bool {
268 let other_key = other.authority_key();
269 self.native_controllers.iter().contains(&other_key)
270 }
271
272 pub fn is_controlled_by(&self, chain: &[DidAccount]) -> bool {
278 match chain {
279 [head, tail @ ..] => match self.is_directly_controlled_by(head) {
280 true => head.is_controlled_by(tail),
281 false => false,
282 },
283 _ => true,
284 }
285 }
286
287 pub fn set_services(&mut self, services: Vec<Service>, allow_duplicates: bool) -> Result<()> {
288 let original_size = services.len();
289 let unique_services = services
292 .into_iter()
293 .unique_by(|x| x.fragment.clone())
294 .collect_vec();
295
296 require!(
297 allow_duplicates || unique_services.len() == original_size,
298 DidSolError::ServiceFragmentAlreadyInUse
299 );
300
301 self.services = unique_services;
302 Ok(())
303 }
304
305 pub fn set_verification_methods(
306 &mut self,
307 existing: Vec<VerificationMethod>,
308 incoming: Vec<VerificationMethod>,
309 ) -> Result<()> {
310 incoming.iter().try_for_each(|vm| {
312 match VerificationMethodFlags::from_bits(vm.flags)
313 .ok_or(DidSolError::ConversionError)?
314 .contains(VerificationMethodFlags::OWNERSHIP_PROOF)
315 {
316 true => Err(DidSolError::VmOwnershipOnAdd),
317 false => Ok(()),
318 }
319 })?;
320
321 let methods = [existing, incoming].concat();
322 let original_size = methods.len();
323 let mut unique_methods = methods
324 .into_iter()
325 .unique_by(|x| x.fragment.clone())
326 .collect_vec();
327 require!(
328 unique_methods.len() == original_size,
329 DidSolError::VmFragmentAlreadyInUse
330 );
331
332 if let Some(index) = unique_methods
336 .iter()
337 .position(|vm| vm.fragment == self.initial_verification_method.fragment)
338 {
339 self.initial_verification_method.flags = unique_methods.swap_remove(index).flags;
340 }
341
342 self.verification_methods = unique_methods;
343
344 Ok(())
345 }
346
347 pub fn set_native_controllers(&mut self, native_controllers: Vec<Pubkey>) -> Result<()> {
348 self.native_controllers = native_controllers.into_iter().unique().collect_vec();
349
350 let own_authority = Pubkey::new(&self.initial_verification_method.key_data);
351
352 require!(
353 !self.native_controllers.contains(&own_authority),
354 DidSolError::InvalidNativeControllers,
355 );
356
357 Ok(())
358 }
359
360 pub fn set_other_controllers(&mut self, other_controllers: Vec<String>) -> Result<()> {
361 self.other_controllers = other_controllers.into_iter().unique().collect_vec();
362
363 require!(
364 check_other_controllers(&self.other_controllers),
365 DidSolError::InvalidOtherControllers
366 );
367
368 Ok(())
369 }
370
371 pub fn try_from(
373 did_account: &AccountInfo,
374 initial_authority: &Pubkey,
375 did_account_seed_bump: Option<u8>,
376 ) -> Result<DidAccount> {
377 if did_account.owner == &System::id() {
378 let (derived_did_account, bump) =
380 if let Some(did_account_seed_bump) = did_account_seed_bump {
381 (
382 derive_did_account_with_bump(
383 &initial_authority.to_bytes(),
384 did_account_seed_bump,
385 )
386 .map_err(|_| Error::from(ErrorCode::ConstraintSeeds))?,
387 did_account_seed_bump,
388 )
389 } else {
390 derive_did_account(&initial_authority.to_bytes())
391 };
392
393 if derived_did_account != *did_account.key {
395 return Err(error!(DidSolError::WrongAuthorityForDid));
396 }
397
398 return Ok(DidAccount::new(bump, initial_authority));
399 }
400 let did_account: Account<DidAccount> = Account::try_from(did_account)?;
402 Ok(did_account.into_inner())
403 }
404
405 pub fn size(&self) -> usize {
406 1 + 1 + 8 + VerificationMethod::default_size() + 4 + self.verification_methods.iter().fold(0, |accum, item| { accum + item.size() }) + 4 + self.services.iter().fold(0, |accum, item| { accum + item.size() }) + 4 + self.native_controllers.len() * 32 + 4 + self.other_controllers.iter().fold(0, |accum, item| { accum + 4 + item.len() })
414 }
416
417 pub fn initial_size() -> usize {
418 1 + 1 + 8 + VerificationMethod::default_size() + 4 + 4 + 4 + 4 }
427}
428
429#[derive(
430 AnchorSerialize, AnchorDeserialize, Copy, Clone, FromPrimitive, ToPrimitive, PartialEq, Eq,
431)]
432pub enum VerificationMethodType {
433 Ed25519VerificationKey2018,
436 EcdsaSecp256k1RecoveryMethod2020,
438 EcdsaSecp256k1VerificationKey2019,
440}
441
442impl VerificationMethodType {
443 pub fn authority_types() -> [VerificationMethodType; 3] {
444 [
445 VerificationMethodType::Ed25519VerificationKey2018,
446 VerificationMethodType::EcdsaSecp256k1VerificationKey2019,
447 VerificationMethodType::EcdsaSecp256k1RecoveryMethod2020,
448 ]
449 }
450
451 }
456
457impl Default for VerificationMethodType {
458 fn default() -> Self {
459 VerificationMethodType::Ed25519VerificationKey2018
460 }
461}
462
463#[derive(AnchorSerialize, AnchorDeserialize, Clone)]
465pub struct VerificationMethod {
466 pub fragment: String,
468 pub flags: u16,
470 pub method_type: u8,
472 pub key_data: Vec<u8>,
475}
476
477impl VerificationMethod {
478 pub fn size(&self) -> usize {
479 4 + self.fragment.len()
480 + 2 + 1 + 4 + self.key_data.len()
483 }
484
485 pub fn default(flags: VerificationMethodFlags, key_data: Vec<u8>) -> VerificationMethod {
486 VerificationMethod {
487 fragment: String::from(VM_DEFAULT_FRAGMENT_NAME),
488 flags: flags.bits(),
489 method_type: VerificationMethodType::default().to_u8().unwrap(),
490 key_data,
491 }
492 }
493
494 pub fn default_size() -> usize {
495 4 + 7 + 2 + 1 + 4 + 32 }
500}
501
502#[derive(AnchorSerialize, AnchorDeserialize, Default, Clone)]
504pub struct Service {
505 pub fragment: String,
506 pub service_type: String,
507 pub service_endpoint: String,
508}
509
510impl Service {
511 pub fn size(&self) -> usize {
512 4 + self.fragment.len() + 4 + self.service_type.len() + 4 + self.service_endpoint.len()
513 }
514}
515
516#[derive(AnchorSerialize, AnchorDeserialize)]
517pub struct Secp256k1RawSignature {
518 pub signature: [u8; 64],
519 pub recovery_id: u8,
520}
521
522bitflags! {
523 pub struct VerificationMethodFlags: u16 {
524 const NONE = 0;
525 const AUTHENTICATION = 1 << 0;
527 const ASSERTION = 1 << 1;
529 const KEY_AGREEMENT = 1 << 2;
531 const CAPABILITY_INVOCATION = 1 << 3;
533 const CAPABILITY_DELEGATION = 1 << 4;
535 const DID_DOC_HIDDEN = 1 << 5;
537 const OWNERSHIP_PROOF = 1 << 6;
539 }
540}