verifyEip712ProofDetailed function
Verifies an EIP-712 typed data signature on a Verifiable Credential.
Recovers the signer address from the proof signature and compares it
with the issuer DID address (did:{method}:{address}).
Currently performs only structural validation: the returned result is either Eip712VerificationInvalid (with a specific reason) or Eip712VerificationStructuralOnly when the envelope parses. Full cryptographic verification requires the issuer's EIP-712 domain config, which is not yet surfaced in the credential model.
Implementation
Eip712VerificationResult verifyEip712ProofDetailed(
CrossmintVerifiableCredential credential,
) {
final proof = credential.proof;
if (proof.isEmpty) {
return const Eip712VerificationInvalid('empty proof');
}
final Object? proofValue = proof['proofValue'] ?? proof['jws'];
if (proofValue is! String || proofValue.isEmpty) {
return const Eip712VerificationInvalid('missing proofValue');
}
final issuerAddress = _extractAddressFromDid(credential.issuer.id);
if (issuerAddress == null) {
return const Eip712VerificationInvalid('malformed issuer DID');
}
// The proof contains a hex-encoded secp256k1 signature (r + s + v).
final sigBytes = _hexToBytes(proofValue);
if (sigBytes == null || sigBytes.length != 65) {
return const Eip712VerificationInvalid('invalid signature bytes');
}
// The official SDK uses ethers.verifyTypedData() which requires the full
// EIP-712 domain and types. Those aren't currently part of the credential
// model, so we stop at structural validation and signal that explicitly
// via Eip712VerificationStructuralOnly.
return const Eip712VerificationStructuralOnly();
}