---
# System prepended metadata

title: DIDDocument building with signature validation

---

# DIDDocument building with signature validation
```Rust

fn build_valid_document(did: &DID, documents: Vec<DIDDocument>, diffs: Vec<DIDDiff>) -> Result<DIDDocument> {
    let did_id = method_id(did)?;
    let mut tracking_doc = DIDDocument::default();
    let mut tracking_auth_key = String::new();
    let mut found_initial_doc = false;
    // 1. verify that document and diffs have correct did and order them
    let mut documents: Vec<DIDDocument> = documents.iter().filter(|doc| &doc.id == did).cloned().collect();
    documents.sort_by(|a, b| a.updated.cmp(&b.updated));
    let mut diffs: Vec<DIDDiff> = diffs.iter().filter(|diff| diff.id == did.clone()).cloned().collect();
    diffs.sort_by(|a, b| a.proof.created.cmp(&b.proof.created));

    // 2. iterate over documents and check signatures
    for doc in &documents {
        // if inital document was found
        if found_initial_doc {
            // Check if auth_key matches the latest
            if get_auth_key(&doc)? == tracking_auth_key {
                //verify signature
                if doc.verify_unchecked().is_ok() {
                    // Update document and tracking_auth_key
                    tracking_doc = doc.clone();
                    tracking_auth_key = get_auth_key(&doc)?;
                }
            }
        // else look for the initial document: if auth_key matches did
        } else if &method_id(&create_method_id(&get_auth_key(&doc)?, Some("com"), None)?)? == &did_id {
            //verify signature
            if doc.verify_unchecked().is_ok() {
                found_initial_doc = true;
                tracking_doc = doc.clone();
                tracking_auth_key = get_auth_key(&doc)?;
            }
        }
    }
    // at this point tracking_doc should be the latest valid document
    // 3. Check signatures and apply diffs
    for diff in diffs {
        // Verify signature
        if tracking_doc.verify_diff_unchecked(&diff).is_ok() {
            // Merge diff
            tracking_doc = tracking_doc.merge(DIDDocument::get_diff_from_str(&diff.diff)?)?;
        }
    }

    if found_initial_doc {
        Ok(tracking_doc)
    } else {
        return Err(anyhow!("No valid document found"));
    }
}

fn get_auth_key(doc: &DIDDocument) -> crate::Result<String> {
    let key_did = doc
        .resolve_key(0, KeyRelation::Authentication)
        .ok_or(Error::InvalidAuthenticationKey)?;
    let key_string = match key_did.key_data() {
        KeyData::PublicKeyBase58(key) => key,
        _ => return Err(anyhow!(Error::InvalidAuthenticationKey)),
    };
    Ok(key_string.to_string())
}

```
