Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
112 commits
Select commit Hold shift + click to select a range
5ec19e6
Initial draft of id cred presentations
soerenbf Oct 14, 2025
dabf98c
Migrate identity proof types to web3 ID
soerenbf Oct 15, 2025
b21d788
Route verifiable presentation requests to the old implementation (for…
soerenbf Oct 16, 2025
2bb8819
Fix compilation errors after restructure
soerenbf Oct 16, 2025
87ba73d
Verifiable presentation V1 tests
soerenbf Oct 16, 2025
76900d4
Add helper functions for creating context and grpc helper functions f…
soerenbf Oct 16, 2025
bb8f398
Add JSON conversion for request + proof types
soerenbf Oct 17, 2025
817f0ea
Fix anchor check
soerenbf Oct 17, 2025
63f0dd6
Fix example
soerenbf Oct 17, 2025
1672e46
Make the breaking changes to `CredentialStatementBuilder` more visible
soerenbf Oct 17, 2025
a01c724
Update changelog with changes introduced
soerenbf Oct 17, 2025
55fbdfd
Add audit types to `VerifiablefpresentationV1`
soerenbf Oct 17, 2025
88f8775
Remove the need for supplying `policy` for identity commitment inputs
soerenbf Oct 17, 2025
5b3ea25
Fix request anchor
soerenbf Oct 17, 2025
e7325f1
Merge branch 'vp-v1/id-proofs-mock' into vp-v1/audit-reports
soerenbf Oct 17, 2025
6d164bc
Fix audit anchor
soerenbf Oct 17, 2025
a5e2893
A little bit of renaming + usability improvements
soerenbf Oct 20, 2025
e29255f
PR feedback
soerenbf Oct 20, 2025
17bd51b
Fix misconception of anchor public info
soerenbf Oct 20, 2025
3e8c54b
Fix lint/tests
soerenbf Oct 20, 2025
1b4e1d9
Merge branch 'vp-v1/id-proofs-mock' into vp-v1/audit-reports
soerenbf Oct 20, 2025
fcca28e
Merge pull request #561 from Concordium/vp-v1/id-proofs-mock
soerenbf Oct 20, 2025
bfb82c5
Merge pull request #562 from Concordium/vp-v1/audit-reports
soerenbf Oct 20, 2025
bda4033
alpha bump
soerenbf Oct 20, 2025
d6d0a17
Merge pull request #565 from Concordium/sdk-bump/12.0.0-alpha.0
soerenbf Oct 20, 2025
1e77bb4
VP V1 integration docs
soerenbf Oct 20, 2025
6486dde
Fix lint
soerenbf Oct 20, 2025
fff93fc
Add section on JSON and audit records
soerenbf Oct 20, 2025
d1ef1e9
Add added page to typedoc config
soerenbf Oct 21, 2025
19c8e7e
Audit record docstrings
soerenbf Oct 21, 2025
cae1281
Docstrings for old undocumented VP code
soerenbf Oct 21, 2025
70e41ed
Add docstrings for verifiable presentation V1 types
soerenbf Oct 21, 2025
5c06bdf
Add docstrings for web3 id types
soerenbf Oct 21, 2025
3c00bc3
Fix build
soerenbf Oct 21, 2025
78fe779
Change description on how to create the verifiable presentation input
soerenbf Oct 21, 2025
0970976
Merge pull request #563 from Concordium/vp-v1/integration-docs
soerenbf Oct 21, 2025
4ee42aa
Add an integration example for creating an identity based verifiable …
soerenbf Oct 22, 2025
3e592ea
Merge branch 'bugfix/rust-bindings-nodejs-esm-compat' into vp-v1/inte…
soerenbf Oct 22, 2025
543575a
Fix issue with anchor discrepancy when serializing/deserializing the …
soerenbf Oct 22, 2025
bcf0ad6
Version bump
soerenbf Oct 22, 2025
8dab51f
Fix failing test due to anchor computation change
soerenbf Oct 22, 2025
8c0f6a0
Merge branch 'release/sdk/12' into vp-v1/code-doc
soerenbf Oct 22, 2025
04428bf
Merge branch 'main' into vp-v1/integration-example
soerenbf Oct 22, 2025
0a54af3
Fix help message
soerenbf Oct 22, 2025
a13e3bb
Merge pull request #566 from Concordium/vp-v1/code-doc
soerenbf Oct 22, 2025
80db325
Fix missing change in changelog
soerenbf Oct 22, 2025
a01189e
Merge branch 'release/sdk/12' into vp-v1/integration-example
soerenbf Oct 23, 2025
e731db3
Merge pull request #569 from Concordium/vp-v1/integration-example
soerenbf Oct 23, 2025
997c7ed
Align audit record with ADR
soerenbf Oct 27, 2025
462689e
Update changelog
soerenbf Oct 27, 2025
9200db0
Align audit record/anchor documentation
soerenbf Oct 27, 2025
3b38ce8
Version bump
soerenbf Oct 27, 2025
7164298
Update docs/pages/verifiable-presentations.md
soerenbf Oct 28, 2025
fe2239b
Merge branch 'bugfix/wasm-pack-install' into vp-v1/audit-record-version
soerenbf Oct 28, 2025
9ae2c41
Merge branch 'vp-v1/audit-record-version' of github.com:Concordium/co…
soerenbf Oct 28, 2025
7ed661e
Fix example
soerenbf Oct 28, 2025
3693f33
Merge branch 'main' into vp-v1/audit-record-version
soerenbf Oct 28, 2025
09e417f
..
soerenbf Oct 29, 2025
2be985a
Roll back changes introduced mainly to retrofit new protocol into the…
soerenbf Oct 29, 2025
49c1b3f
Scope request and proof inputs to the respective VP version
soerenbf Oct 29, 2025
86223ae
Explicit versioning for audit record/anchor
soerenbf Oct 29, 2025
536f19f
More re-scoping
soerenbf Oct 29, 2025
1859290
Add statement builder for v1 VPR
soerenbf Oct 29, 2025
838d372
Fix build errors
soerenbf Oct 29, 2025
d4b077c
Update docs + changelog
soerenbf Oct 29, 2025
90dedce
lock request anchor data version
soerenbf Oct 29, 2025
e83f346
Move stuff back...
soerenbf Oct 29, 2025
6caa897
Add documentation
soerenbf Oct 30, 2025
c155316
Align identity statement DID with preliminary implementation in conco…
soerenbf Oct 30, 2025
3c20a13
Apply suggestions from code review
soerenbf Oct 31, 2025
061ac15
Apply suggestions from code review
soerenbf Oct 31, 2025
bbb1d88
Better explanation of statement types and conversion between them.
soerenbf Oct 31, 2025
0902f1e
Remove web3 ID from VPV1 implementation
soerenbf Oct 31, 2025
06d657c
Merge pull request #574 from Concordium/vp-v1/align-request-statements
soerenbf Oct 31, 2025
3452b19
Fix id statement did
soerenbf Nov 3, 2025
713d7c0
Add JSON fixtures
soerenbf Nov 3, 2025
c4768a9
Merge pull request #578 from Concordium/vp-v1/fix-cred-statement-did
soerenbf Nov 3, 2025
41f6eaa
Merge branch 'release/sdk/11.1' into vp-v1/json-fixtures
soerenbf Nov 3, 2025
4ef4418
Fix failing browser test
soerenbf Nov 4, 2025
a398750
Merge branch 'vp-v1/json-fixtures' of github.com:Concordium/concordiu…
soerenbf Nov 4, 2025
1aab81d
convert ts to JSON fixtures
soerenbf Nov 4, 2025
94d65b8
Align names with base
soerenbf Nov 5, 2025
9f399a7
Statement -> Claims
soerenbf Nov 5, 2025
bff9792
JSON representation alignment
soerenbf Nov 5, 2025
73f9492
CredentialsInputs -> VerificationMaterial
soerenbf Nov 5, 2025
94779ab
..
soerenbf Nov 5, 2025
7322756
Fix md links
soerenbf Nov 6, 2025
af3e6ec
Fix build
soerenbf Nov 6, 2025
c8d7435
Expose function to rust-bindings for creating v1 presentations
soerenbf Nov 5, 2025
8942430
Connect presentation creation to rust-bindings
soerenbf Nov 5, 2025
718e9e5
Align with base representation
soerenbf Nov 5, 2025
a4b6a09
fmt
soerenbf Nov 6, 2025
f9cd0e8
Update base ref
soerenbf Nov 6, 2025
ed329c8
Fix build due to change type name in protobuf
soerenbf Nov 6, 2025
6b6b807
Fix lint
soerenbf Nov 6, 2025
007a1cf
Update base ref to #796
soerenbf Nov 6, 2025
03fe943
Simplify implementation
soerenbf Nov 6, 2025
04c2473
Add presentation verification function to rust-bindings
soerenbf Nov 6, 2025
bfbd665
Move credentials into it's own module
soerenbf Nov 6, 2025
f938e94
Route presentation verification functionality into concordium-base
soerenbf Nov 6, 2025
39b3117
Account based credential verification works
soerenbf Nov 6, 2025
8eb819e
Identity based verification works
soerenbf Nov 6, 2025
7fb5031
Look up id credential on-chain public info
soerenbf Nov 7, 2025
def3372
Merge pull request #583 from Concordium/vp-v1/naming-alignment
soerenbf Nov 7, 2025
3705596
Merge pull request #584 from Concordium/vp-v1/rust-bindings
soerenbf Nov 7, 2025
b6e3aaf
Merge branch 'release/sdk/11.1' into vp-v1/verify-presentation
soerenbf Nov 7, 2025
d915261
Update changelog
soerenbf Nov 7, 2025
64c65c4
fmt
soerenbf Nov 7, 2025
cc00bbd
Prepare for release
DOBEN Nov 7, 2025
8d737e6
Merge pull request #587 from Concordium/vp-v1/verify-presentation
DOBEN Nov 7, 2025
8638e9d
Fix
DOBEN Nov 7, 2025
e1fe003
Merge pull request #590 from Concordium/fix-missing-version-bump
DOBEN Nov 7, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion deps/concordium-base
Submodule concordium-base updated 239 files
255 changes: 255 additions & 0 deletions docs/pages/verifiable-presentations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,255 @@
# Verifiable Presentations (V1)

This document describes how to create v1 verifiable presentations and how to verify them.

**Table of Contents:**
<!--toc:start-->
- [Build Statement](#build-statement)
- [Identity/account credential statements](#identityaccount-credential-statements)
- [JSON representation](#json-representation)
- [Verification Request](#verification-request)
- [Verifiable Presentation](#verifiable-presentation)
- [Verifiable Audit Record](#verifiable-audit-record)
<!--toc:end-->

## Build Statement

The SDK contains a helper to create statements about identities, which can
then be proven.

To do so, use the _presentation request statement builder_, to build a statement:

{@codeblock ~~:nodejs/common/verifiable-credential-statements.ts#documentation-snippet}

### Identity/account credential statements

To build a statement against an identity credential, the builder has two different entrypoints, which
have an identical function signature, which consists of

1. A list of identity providers that the identity must be created from
2. A callback function which should be used to add statements for the credential

```ts
// used for proofs tied to an account created from the identity credential.
builder.addAccountStatement([0,2].map(idp => new IdentityProviderDID('Testnet', idp)), (build) => ...)
// used for proofs which are not tied to a specific account
builder.addIdentityStatement([0,2].map(idp => new IdentityProviderDID('Testnet', idp)), (build) => ...)
// alternatively let the application producing the proof decide
builder.addAccountOrIdentityStatement([0,2].map(idp => new IdentityProviderDID('Testnet', idp)), (build) => ...)
```

Below are a set of functions accessible for the `build` object passed in the callback

#### Minimum Age

There is a helper function for specifying the prover must have some minimum
age.

Example: add the statement that the prover must be at least 18 years old:

```ts
build.addMinimumAge(18);
```

#### Maximum Age

There is a helper function for specifying the prover must have some maximum
age.

Example: add the statement that the prover must be at most 27 years old:

```ts
build.addMaximumAge(27);
```

#### EU membership

There are helpers for specifying the country of residency or nationality to
be one of the EU member states.

```ts
build.addEUNationality();
build.addEUResidency();
```

#### Reveal statement

State that a given attribute should be revealed as part of the proof.

```ts
build.revealAttribute(AttributesKeys.nationality);
```

#### Range statement

State that a given attribute should be between 2 given values.

Example: add the statement that the prover must be born between January 1,
1941 and Februar 2, 2005.

```ts
build.addRange(AttributesKeys.dob, 19410101, 20050202);
```

Note that this type of statement is only allowed for the following attributes:

- dob (date of birth)
- idDocIssuedAt
- idDocExpiresAt

#### Membership statement

Example: add the statement that the prover's country of residency is France or Spain,
specified in ISO3166-1 alpha-2 format:

```ts
build.addMembership(AttributesKeys.CountryOfResidency, ['FR', 'ES']);
```

Note that this type of statement is only allowed for the following attributes:

- Nationality
- CountryOfResidency
- IdDocIssuer
- IdDocType

#### Non membership statement

Example: add the statement that the prover's country of residency not Germany
nor Portugal:

```ts
build.addNonMembership(AttributesKeys.CountryOfResidency, ['DE', 'PT']);
```

Note that this type of statement is only allowed for the following attributes:

- Nationality
- CountryOfResidency
- IdDocIssuer
- IdDocType

## JSON representation

The `VerificationRequestV1`, `VerifiablePresentationV1`, and `VerifiableAuditRecordV1` can be represented as
JSON by calling the associated `.toJSON` method (will also be called implicitly with `JSON.stringify`). Correspondingly,
parsing the JSON values can be done with the `.fromJSON` function exposed for each type.

> bigints are used internally in the types described above and need to be handled with something like `json-bigint`

Example: service serializes presentation request in response to frontend; frontend deserializes and parses the JSON.

```ts
const json = JSON.stringify(presentationRequest); // service sends back presentation request to frontend
...
const presentationRequest = VerificationRequestV1.fromJSON(JSON.parse(json)); // frontend parses the JSON.
```

## Verification Request

To get a _verifiable presentation_ of one or more _verifiable credentials_ owned by a user, the entity requesting
the information must first build a _verification request_. In the V1 protocol, this is done in the following
sequence:

1. Make the _request context_, consisting of
a. a unique 32-byte "nonce"
b. a "connection ID" which identifies the connection between prover and requester
c. a "context string" which describes the context of the proof request, e.g. which store is being accessed
d. a set of requested context values, identified by their labels. For now the defaults here are: the block hash of the
anchor transaction and the resource ID (i.e. an identifier of the requester, e.g. a url of the website). The
requested context is filled out by the application creating the proof.
2. [Build the statement](#build-statement) to be proven by the user

Once this is done, the request must be _anchored_ on chain with a transaction. This can be achieved by calling

```ts
const nonce = Uint8Array.from(...) // randomly generated 32-byte value
const connectionID = ... // e.g. a wallet-connect ID
const contextString = 'My compliant web3 wine shop'
const context = VerificationRequestV1.createSimpleContext(nonce, connectionID, contextString)

const statement = new VerificationRequestV1.statementBuilder()...

// a GRPC client connected a node on the network the anchor should be registered on
const grpcClient: ConcordiumGRPCClient = ...;
// the sender of the anchor transaction
const sender: AccountAddress.Type = ...;
// the keys for the account to sign the anchor transaction
const signer: Signer = ...;

// create the verification request with an on-chain anchor, which can be checked by the owner of the credentials.
const verificationRequest = await VerificationRequestV1.createAndAchor(
grpcClient,
sender,
signer,
context,
statement
);
```

## Verifiable Presentation

Computing a _verifiable presentation_ from a _verifiable presentation request_ is a process of the following sequence
for each credential statement in the request:

1. Identify valid credentials for the statement by looking at the ID qualifier of the `VerificationRequestV1.Statement`.
2. Validate the attributes of the credential in the context of the statement.
3. Construct a `VerifiablePresentationV1.Statement` corresponding to the credential. This is is _not_ the same as the
`VerificationRequestV1.Statement` we built for the `VerificationRequestV1` previously; here we're working with
a specific credential, e.g. from the users wallet.
a. for `VerificationRequestV1.IdentityStatement`s, the `source` also needs to be taken into account. This
specifies the type of credential requested by the dapp. This can either be set to
`["Identity"] | ["Account"] | ["Identity", "Account"]`, where the latter means that the application constructing
the proof can decide which proof to construct for the statement.

When this is done for all credential statements in the request, we construct the _proof context_ corresponding to the
_request context_ of the request, specifying values for each requested context value in
`VerificationRequestV1.Context.requested`.

```ts
// specify the resource ID (e.g. website URL or fingerprint of TLS certificate that the wallet is connected to)
// from the connection to the requester of the proof. The block hash is _not_ specified here, as it is looked up
// later in `VerifiablePresentationV1.createFromAnchor` from the anchor transaction reference in the presentation
// request.
const contextValues: GivenContext[] = [{label: 'ResourceID', context: ...}];

// The application goes through each statement in the verification request, and constructs a corresponding statement
// used as input to the presentation. The difference between the two statement types boil down to the presence of an ID
// qualifier vs. an ID (selected by the application based on the id qualifier).
const statements: VerifiablePresentationV1.SubjectClaims[] = verificationRequest.credentialStatements.map((entry) => {
// prioritize creating identity based proofs, as these are more privacy-preserving
if (entry.source.includes('identity'))
return VerifiablePresentationV1.createIdentityClaims(..., entry.statement);
return VerifiablePresentation.createAccountClaims(..., entry.statement);
});

// the inputs for the credential owned by the user, i.e. credential attribute values. For each
// `SpecifiedCredentialStatement`, there should be a corresponding input
const inputs: CommitmentInput[] = [
createIdentityCommitmentInputWithHdWallet(...),
createAccountCommitmentInputWithHdWallet(...),
];

const presentation = await VerifiablePresentationV1.createFromAnchor(
grpcClient,
verificationRequest,
statements,
inputs,
contextValues
);

// verify the presentation elsewhere
const result = VerifiablePresentationV1.verifyWithNode(presentation, verificationRequest, grpcClient, network);
```

## Verifiable Audit Record

Services can opt in to create a _verification audit record_ from the _verification request_ and corresponding
_verifiable presentation_. This exists as a record and a corresponding anchor. The record should be stored by the dapp backend (e.g. in a database),
and the anchor should be registered on chain. The transacton hash of the anchor registration should be stored along the record.

```ts
const uuid: string = ...;
const record = VerificationAuditRecordV1.create(uuid, verificationRequest, presentation);
const anchorTransactionHash = await VerificationAuditRecordV1.registerAnchor(record, grpcClient, sender, signer);
```
4 changes: 4 additions & 0 deletions docs/typedoc.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ module.exports = {
name: 'Identity Proofs',
source: 'identity-proofs.md',
},
{
name: 'Verifiable presentations',
source: 'verifiable-presentations.md',
},
{
name: 'Runnable Examples',
source: 'runnable-examples.md',
Expand Down
23 changes: 23 additions & 0 deletions examples/nodejs/common/verifiable-credential-statements.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { IdentityProviderDID, VerificationRequestV1 } from '@concordium/web-sdk';

// #region documentation-snippet
let builder = VerificationRequestV1.statementBuilder();

// Add an identity credential statement. Alternatively, if the proof produced from the
// statement should be tied to an account, use `builder.addAccountStatement`.
// A third option `builder.addAccountOrIdentityStatement`exists where it's up to the
// application holding the credentials to decide which proof is produced.
builder = builder.addIdentityStatement(
[0, 1].map((idpIndex) => new IdentityProviderDID('Testnet', idpIndex)),
(b) => {
b.addMinimumAge(18);
b.addEUResidency();
b.revealAttribute('firstName');
}
);

// Get the complete statement to request a proof of.
const statement = builder.getStatements();

console.log('successfully constructed statement', statement);
// #endregion documentation-snippet
2 changes: 2 additions & 0 deletions examples/nodejs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
"@concordium/web-sdk": "workspace:^",
"@grpc/grpc-js": "^1.14.0",
"@noble/ed25519": "^2.0.0",
"@types/json-bigint": "^1.0.4",
"buffer": "^6.0.3",
"json-bigint": "^1.0.0",
"meow": "11.0",
"node-fetch": "^3.3.2"
},
Expand Down
Loading