Generic attest over a JSON-LD value — the *one* canonicalization/signing path all typed nodes share. Fills `attributedTo` (from the identity's `did:atomic`) when absent, computes the content hash over `hashing_view`, signs `jcs(signing_view)`, and attaches the proof. Returns the value.
(mut value: Value, identity: &Identity, keypair: &KeyPair)
| 111 | /// `did:atomic`) when absent, computes the content hash over `hashing_view`, |
| 112 | /// signs `jcs(signing_view)`, and attaches the proof. Returns the value. |
| 113 | pub fn attest_value(mut value: Value, identity: &Identity, keypair: &KeyPair) -> Value { |
| 114 | let did = did::did_for_public_key(&identity.public_key); |
| 115 | |
| 116 | if let Some(obj) = value.as_object_mut() { |
| 117 | // Fill attributedTo only if there is no non-empty value already. |
| 118 | let has_author = obj |
| 119 | .get(PROP_ATTRIBUTED_TO) |
| 120 | .and_then(Value::as_str) |
| 121 | .map(|s| !s.is_empty()) |
| 122 | .unwrap_or(false); |
| 123 | if !has_author { |
| 124 | obj.insert(PROP_ATTRIBUTED_TO.to_string(), Value::String(did.clone())); |
| 125 | } |
| 126 | } |
| 127 | |
| 128 | // Hash first (over the value without proof/contentHash), then sign (over |
| 129 | // the value with contentHash, without proof). |
| 130 | let content_hash = hash::content_hash(&hashing_view(&value)); |
| 131 | if let Some(obj) = value.as_object_mut() { |
| 132 | obj.insert(PROP_CONTENT_HASH.to_string(), Value::String(content_hash)); |
| 133 | } |
| 134 | |
| 135 | let signing_bytes = jcs::canonicalize(&signing_view(&value)).into_bytes(); |
| 136 | let signature = Signer::new(keypair).sign(&signing_bytes); |
| 137 | let proof = Proof { |
| 138 | type_: PROOF_TYPE.to_string(), |
| 139 | cryptosuite: CRYPTOSUITE.to_string(), |
| 140 | verification_method: did::verification_method(&did), |
| 141 | proof_purpose: PROOF_PURPOSE.to_string(), |
| 142 | proof_value: encode_proof_value(&signature), |
| 143 | }; |
| 144 | if let Some(obj) = value.as_object_mut() { |
| 145 | obj.insert( |
| 146 | PROP_PROOF.to_string(), |
| 147 | serde_json::to_value(proof).expect("proof serialization is infallible"), |
| 148 | ); |
| 149 | } |
| 150 | value |
| 151 | } |
| 152 | |
| 153 | /// Generic verify over a JSON-LD value — the same three checks as the typed |
| 154 | /// path: (1) the content hash recomputes over `hashing_view`, (2) the signature |