Skip to content

proof/proof-vc-common

Repository files navigation

Proof Digital Credentials

drawing

A digital passport. Verified once, usable everywhere.

Read our documentation or try it!

Table of Contents

Installation

npm install @proof.com/proof-vc-common

The library provides 2 distinct browser and Node.js distributions, see package.json exports. The browser distribution has 0 dependencies

Getting Started

Proof implements the OpenID for Verifiable Presentations 1.0 specification. Setup an OAuth Application in your Proof account to get your client_id.

Initialize the library at the start of your application:

import { init } from "@proof.com/proof-vc-common";

init({
  environment: "sandbox",
  client_id: "verifier-demo",
  response_mode: "direct_post",
  callback_uri: "http://localhost/verify_vp_token",
});

Response Modes

Proof supports fragment and direct_post response modes.

fragment

Using fragment the vp_token is returned as a fragment of the callback_uri when the user is 302 redirected from Proof to your website.

GET http://localhost/verify_vp_token#vp_token=eyJwcm9vZl9pZF9...

direct_post

Using direct_post the vp_token is returned in the JSON body of a POST request to the callback_uri from Proof to your website. See the OID4VP specification for more details.

POST http://localhost/verify_vp_token
{ "vp_token": "eyJwcm9vZl9pZF9..." }

Pushed Authorization Requests

Proof supports Pushed Authorization Requests (PAR). You may want to use this feature when using Transaction Templates to avoid hitting URL size limits.

init({
  environment: "sandbox",
  client_id: "caxdw5a7d",
  response_mode: "direct_post",
  callback_uri: "http://localhost/verify_vp_token",
  use_pushed_authorization_request: true,
});

Verifiable Credential Presentation

Credential Type

Proof issues Verifiable Credentials according to the SD-JWT-VC specification and publishes its OID4VCI Credential Issuer Metadata at https://api.proof.com/.well-known/openid-credential-issuer.

ProofCredentialV1

claim type description
given_name string user's given name as it appears on the verified identity document
family_name string user's family name as it appears on the verified identity document
birthdate string user's date of birth in ISO 8601 format (YYYY-MM-DD)
age_is_over.18 boolean boolean confirming the user is 18 or older
age_is_over.21 boolean boolean confirming the user is 21 or older
age_is_over.65 boolean boolean confirming the user is 65 or older

All attributes are selectively disclosable and will return undefined if the claim wasn't disclosed.

Request

Request a Verifiable Credential Presentation with an OAuth 2.0 Authorization Request:

import { getAuthorizationRequestURL } from "@proof.com/proof-vc-common";

const redirect = getAuthorizationRequestURL({
  nonce: "3e8e4918-e9fb-453a-a538-81152be15c1b",
  scope: "urn:proof:params:scope:verifiable-credentials:basic",
  state: "6A2B4CD830",
  login_hint: "frodo.baggins@theshire",
});

window.location.href = redirect;

Scopes

Proof supports the scope parameter of the OID4VP specification. Each scope maps to a pre-defined DCQL query and returns a specific Credential Type.

Supported scope and their associated Credential Type:

scope Credential Type
urn:proof:params:scope:verifiable-credentials:basic ProofCredentialV1

Transaction Templates

Transaction Templates allow you to bind specific data to a Verifiable Credential Presentation. Proof uses the Transaction Data parameter of the OID4VP specification. The data is shown to the user during the Presentation flow and the user signs it with a Key Binding JWT (KB-JWT). The KB-JWT is returned as part of the Presentation.

The following Transaction Templates are available:

urn:proof:params:vc:transaction-data:wire-instructions:v1

import {
  getAuthorizationRequestURL,
  transactionData,
} from "@proof.com/proof-vc-common";

const data = transactionData.wireInstructions({
  recipient: {
    institution_name: "Crestline Financial",
    individual_name: "Acme Corp LLC",
    routing_number: "055000123",
    account_number: "7293",
  },
  source: {
    institution_name: "Sterling & Union",
    individual_name: "Sterling & Union",
    account_number: "4821",
    routing_number: "091000456",
  },
  amount: 5000,
  currency: "USD",
  memo: "Invoice #2024-089",
});
const redirect = getAuthorizationRequestURL({
  nonce: "3e8e4918-e9fb-453a-a538-81152be15c1b",
  scope: "urn:proof:params:scope:verifiable-credentials:basic",
  state: "6A2B4CD830",
  login_hint: "frodo.baggins@theshire",
  transaction_data: data,
});

urn:proof:params:vc:transaction-data:payment-itemized:v1

import {
  getAuthorizationRequestURL,
  transactionData,
} from "@proof.com/proof-vc-common";

const data = transactionData.paymentItemized({
  title: "Drive Shaft",
  description: "The Roadhouse (18+), May 6 2026",
  currency: "USD",
  items: [
    { quantity: 2, unit_cost: 40.0, label: "General Admission" },
    { quantity: 2, unit_cost: 11.4, label: "Fees" },
  ],
});
const redirect = getAuthorizationRequestURL({
  nonce: "3e8e4918-e9fb-453a-a538-81152be15c1b",
  scope: "urn:proof:params:scope:verifiable-credentials:basic",
  state: "6A2B4CD830",
  login_hint: "frodo.baggins@theshire",
  transaction_data: data,
});

urn:proof:params:vc:transaction-data:payment-mandate:v1

import {
  getAuthorizationRequestURL,
  transactionData,
} from "@proof.com/proof-vc-common";

const data = transactionData.paymentMandate({
  payment_instrument: {
    type: "wallet",
    id: "did:example:visa-token-7829",
    description: "Visa ••••7829",
  },
  payee: {
    id: "did:example:summitco",
    name: "Summit Co",
    website: "summitco.com",
  },
  prompt_summary:
    "Find me a 4-season backpacking tent from Summit Co under $500",
  amount: 500,
  currency: "USD",
});
const redirect = getAuthorizationRequestURL({
  nonce: "3e8e4918-e9fb-453a-a538-81152be15c1b",
  scope: "urn:proof:params:scope:verifiable-credentials:basic",
  state: "6A2B4CD830",
  login_hint: "frodo.baggins@theshire",
  transaction_data: data,
});

Verify

Decode and verify a Verifiable Presentation's vp_token server-side:

import { init, verifyVPToken } from "@proof.com/proof-vc-common";

init({
  environment: "sandbox",
  client_id: "verifier-demo",
  callback_uri: "https://demo.next.proof.com/",
});

const vpToken = "eyJwcm9vZl9pZ...";
const presentation = verifyVPToken({
  encodedVPToken: vpToken,
  nonce: "3e8e4918-e9fb-453a-a538-81152be15c1b",
});
const verifiableCredential = presentation["proof_id_default"][0];

if (verifiableCredential.isOver18()) {
  purchaseItem();
} else {
  userNotOver18();
}

Verify a single SD-JWT-VC:

import { init, verify } from "@proof.com/proof-vc-common";

init({
  environment: "sandbox",
  client_id: "verifier-demo",
  callback_uri: "https://demo.next.proof.com/",
});

const encodedSDJWT = "eyJraWQiOiI3...";
const verifiableCredential = verify({
  encodedSDJWT,
  nonce: "3e8e4918-e9fb-453a-a538-81152be15c1b",
});

if (verifiableCredential.isOver18()) {
  purchaseItem();
} else {
  userNotOver18();
}

Certificate Authority

Proof's Verifiable Credentials are issued by our Certificate Authority following the CA/B Forum Baseline Requirements for the Issuance and Management of Publicly-Trusted TLS Server Certificates published at https://www.cabforum.org.

The Proof Root CA R1 Certificate is published at http://cert.proof.com/proof-root-ca-r1.crt and is also committed in this repository proof-root-ca-r1.crt.

The sandbox Root CA R1 Development certificate is also committed in this repository proof-root-ca-r1-development.crt and used when environment: "sandbox".

Documentation

Digital Credentials guides https://dev.proof.com/docs/digital-credentials-overview
API Documentation https://dev.proof.com/reference/authorizeverifiablecredentialpresentation

Contributing

Contribution guidelines for this project