loading
Note:
The page never enumerates what the user holds The browser lists the wallets holding something that matches, the user picks one and sees exactly which claims are being asked for, and only then is anything released. A request the user declines is indistinguishable from having nothing - which is the property that makes this safe to offer.
Warning:
Experimental, and server-side by nature Chromium on Android leads here; the protocols are still moving, so branch on IsProtocolSupported rather than on a version. Build the request object on your server - it is signed, and what it asks for is what the wallet shows the user - and verify the response there too: its signature, its issuer, and the nonce you put in the request. Needs a secure context, a user gesture, and a top-level page (or an iframe with allow="digital-credentials-get").

Support checks

IsSupported / IsProtocolSupported

Whether the runtime exposes window.DigitalCredential, and whether it will speak a given exchange protocol. During prerender/SSR these return false rather than throwing, so defer them to OnAfterRenderAsync.

C#
@inject Bit.Butil.DigitalCredentials digitalCredentials

var supported = await digitalCredentials.IsSupported();
var openid4vp = await digitalCredentials.IsProtocolSupported("openid4vp");
Live sample
Protocol
support check output
Results will appear here when you interact with the samples.

Present a credential

Get

Opens the wallet chooser and resolves with the presentation the wallet signed, or null when the user declined, nothing matched, or the browser refused. Must be called from a user-gesture handler. Data arrives as raw JSON - hand it to the server as it stands.

C#
var response = await digitalCredentials.Get(
[
    new DigitalCredentialRequest
    {
        Protocol = "openid4vp",
        Data = serverBuiltPresentationRequest   // signed, built on the server
    }
], CredentialMediation.Required);

if (response is not null)
{
    // POST response.Data to the backend and verify it there.
}
Live sample
Request object (JSON)
present credential output
Results will appear here when you interact with the samples.

Issue a credential into the wallet

Create

The other direction, for an issuer that has already established who the user is. Newer than Get and thinner on the ground, so check for it before offering it. Null when the user declined or no wallet accepted it.

C#
var issued = await digitalCredentials.Create(
[
    new DigitalCredentialRequest
    {
        Protocol = "openid4vci",
        Data = serverBuiltIssuanceRequest
    }
]);
Live sample
Issuance request object (JSON)
issue credential output
Results will appear here when you interact with the samples.

API reference

Member
Signature
Description
IsSupported
ValueTask<bool> IsSupported()
True when the runtime exposes window.DigitalCredential. Returns default (false) during prerender/SSR instead of throwing.
IsProtocolSupported
ValueTask<bool> IsProtocolSupported(string protocol)
Whether the browser will speak an exchange protocol, e.g. openid4vp. The set is expected to change.
Get
ValueTask<DigitalCredentialResponse?> Get(DigitalCredentialRequest[] requests, CredentialMediation mediation = CredentialMediation.Required, CancellationToken cancellationToken = default)
Asks the wallet to present a credential. Null when declined, unmatched or refused. Needs a user gesture.
Create
ValueTask<DigitalCredentialResponse?> Create(DigitalCredentialRequest[] requests, CancellationToken cancellationToken = default)
Issues a credential into the wallet. Null when declined or unsupported. Needs a user gesture.
Abort
ValueTask<bool> Abort()
Ends the exchange this instance started, dismissing the wallet chooser. False when nothing was pending.
DigitalCredentialRequest
string Protocol, object Data
The protocol to speak and that protocol's request object - built and signed on the server.
DigitalCredentialResponse
string Protocol, JsonElement Data
What the wallet returned, as raw JSON. Verify it server-side; reading the claims in the browser proves nothing.
An unhandled error has occurred. Reload 🗙