Skip to content

Conversation

@allanbrondum
Copy link
Contributor

@allanbrondum allanbrondum commented Nov 14, 2025

Purpose

Implement high-level verification functionality that validates a presentation together with an anchored verification requests, and submits audit anchor.

Changes

Verification logic is implemented in base anchor::verify_presentation_with_request_anchor and called
once all needed data has been looked up.

Checklist

  • My code follows the style of this project.
  • The code compiles without warnings.
  • I have performed a self-review of the changes.
  • I have documented my code, in particular the intent of the
    hard-to-understand areas.
  • (If necessary) I have updated the CHANGELOG.

@allanbrondum allanbrondum marked this pull request as draft November 18, 2025 15:40
@allanbrondum allanbrondum marked this pull request as ready for review November 24, 2025 15:16
Comment on lines -1 to -109
//! Types and functions used in Concordium verifiable presentation protocol version 1.
use crate::v2::{self, RPCError};
use concordium_base::web3id::v1::anchor::{
VerificationAuditRecord, VerificationRequest, VerificationRequestData,
};
use concordium_base::{
base::Nonce,
common::{
cbor::{self, CborSerializationError},
types::TransactionTime,
},
contracts_common::AccountAddress,
hashes::TransactionHash,
transactions::{send, BlockItem, ExactSizeTransactionSigner, TooLargeError},
};
use std::collections::HashMap;

#[derive(thiserror::Error, Debug)]
pub enum CreateAnchorError {
#[error("node query error: {0}")]
Query(#[from] v2::QueryError),
#[error("data register transaction data is too large: {0}")]
TooLarge(#[from] TooLargeError),
#[error("CBOR serialization error: {0}")]
CborSerialization(#[from] CborSerializationError),
}

impl From<RPCError> for CreateAnchorError {
fn from(err: RPCError) -> Self {
CreateAnchorError::Query(err.into())
}
}

/// Metadata for transaction submission.
pub struct AnchorTransactionMetadata<'a, S: ExactSizeTransactionSigner> {
/// The signer object used to sign the on-chain anchor transaction. This must correspond to the `sender` account below.
pub signer: &'a S,
/// The sender account of the anchor transaction.
pub sender: AccountAddress,
/// The sequence number for the sender account to use.
pub account_sequence_number: Nonce,
/// The transaction expiry time.
pub expiry: TransactionTime,
}

/// Submit verification request anchor (VRA) and return the verification request.
/// Notice that the VRA will only be submitted, it is not included on-chain yet when
/// the function returns. The transaction hash is returned
/// in [`VerificationRequest::anchor_transaction_hash`] and the transaction must
/// be tracked until finalization before the verification request is usable
/// (waiting for finalization can be done in the app that receives the verification request
/// to create a verifiable presentation).
pub async fn submit_verification_request_anchor<S: ExactSizeTransactionSigner>(
client: &mut v2::Client,
anchor_transaction_metadata: AnchorTransactionMetadata<'_, S>,
verification_request_data: VerificationRequestData,
public_info: HashMap<String, cbor::value::Value>,
) -> Result<VerificationRequest, CreateAnchorError> {
let verification_request_anchor = verification_request_data.to_anchor(public_info);
let cbor = cbor::cbor_encode(&verification_request_anchor)?;
let register_data = cbor.try_into()?;

let tx = send::register_data(
&anchor_transaction_metadata.signer,
anchor_transaction_metadata.sender,
anchor_transaction_metadata.account_sequence_number,
anchor_transaction_metadata.expiry,
register_data,
);
let block_item = BlockItem::AccountTransaction(tx);

// Submit the transaction to the chain.
let transaction_hash = client.send_block_item(&block_item).await?;

Ok(VerificationRequest {
context: verification_request_data.context,
subject_claims: verification_request_data.subject_claims,
anchor_transaction_hash: transaction_hash,
})
}

/// Submit verification audit anchor (VAA).
/// Notice that the VAA will only be submitted, it is not included on-chain yet when
/// the function returns. The transaction must
/// be tracked until finalization for the audit record to be registered successfully.
pub async fn submit_verification_audit_record_anchor<S: ExactSizeTransactionSigner>(
client: &mut v2::Client,
anchor_transaction_metadata: AnchorTransactionMetadata<'_, S>,
verification_audit_record: &VerificationAuditRecord,
public_info: HashMap<String, cbor::value::Value>,
) -> Result<TransactionHash, CreateAnchorError> {
let verification_audit_anchor = verification_audit_record.to_anchor(public_info);
let cbor = cbor::cbor_encode(&verification_audit_anchor)?;
let register_data = cbor.try_into()?;

let tx = send::register_data(
&anchor_transaction_metadata.signer,
anchor_transaction_metadata.sender,
anchor_transaction_metadata.account_sequence_number,
anchor_transaction_metadata.expiry,
register_data,
);
let item = BlockItem::AccountTransaction(tx);

// Submit the transaction to the chain.
let transaction_hash = client.send_block_item(&item).await?;

Ok(transaction_hash)
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved to v1 module (parent module)

@allanbrondum allanbrondum merged commit e8e4b01 into verifiable-presentations-from-id-credentials-feature Dec 2, 2025
4 checks passed
@allanbrondum allanbrondum deleted the ar/run-51-support-a-verify-function-in-the-rust-sdk-support-for branch December 2, 2025 11:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants