Universal Wallet 2020

This specification describes a portable, extensible, JSON-LD wallet representation, supporting digital currencies and credentials.

W3C Editor's Draft

This version:
https://w3id.org/wallet
Latest published version:
https://www.w3.org/TR/universal-wallet-2020/
Latest editor's draft:
https://w3id.org/wallet
Editor:
Orie Steele (Transmute)
Authors:
Orie Steele (Transmute)
Margo Johnson (Transmute)
Guillaume Dardelet (Transmute)
Michael Prorock (mesur.io)
Sudesh Shetty (SecureKey)
Kim Hamilton Duffy (Massachusetts Institute of Technology)
Participate:
GitHub w3c-ccg/universal-wallet-interop-spec
File a bug
Commit history
Pull requests

Abstract

This specification describes a portable, extensible, JSON-LD wallet, supporting digital currencies and credentials.

Status of This Document

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at https://www.w3.org/TR/.

This document is experimental and is undergoing heavy development. It is inadvisable to implement the specification in its current form. An experimental implementation is available.

This document was published by the Credentials Community Group as an Editor's Draft.

GitHub Issues are preferred for discussion of this specification. Alternatively, you can send comments to our mailing list. Please send them to public-credentials@w3.org (archives).

Publication as an Editor's Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

This document was produced by a group operating under the W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

This document is governed by the 1 March 2019 W3C Process Document.

Introduction

Traditional physical wallets are used to store a variety of personal assets such as cash, credit cards, driver license, health insurance, and business cards. Today we also have a wide variety of digital wallets to store and access digital versions of these same assets, with more options coming into the market every day. However, each wallet represents data and capabilities differently, sometimes intentionally to facilitate vendor lock in.

Imagine you had to carry a dozen different wallets with you at all times, and to use each one independently based on the situation. The wallets are disconnected, and the burden is on either the holder or the verifier to request all required information for each transaction. The result is a cumbersome user experience (not dissimilar to account and password management today) and expensive business implementation to support different wallets. What is missing is a standardized structure - a universal wallet - that can effectively point to and comprehend each digital asset in its current location. This universal wallet not only offers a convenient access point for people and machines to organize their assets (akin to a traditional physical wallet), but it also enables awareness and relationships between those assets as needed for real-world use.

The purpose of this specification is to design an abstract data model and set of interfaces that approximate a physical wallet system and its common uses.

There are many existing software systems which manage subsets or supersets of the information represented in digital wallets. This specification aims to be compatible with those systems, by allowing them to continue to manage the information and inferfaces, so long as they can be adequately described at both a data model, and interface level.

The property of representing data and interfaces as they exist, where they exist today, is a critical component of this specification. We fully expect this specification to live or die by its ability to achieve this property.

Guidance

Several organizations have published guidance on digital wallets.

EUDI

European Digital Identity (EUDI) Wallet Solution

Wallet Architecture and Reference Framework

ESI

Electronic Signatures and Infrastructures (ESI)

JAdES digital signatures

SVIP

Department of Homeland Security (DHS) Science and Technology Directorate (S&T) Silicon Valley Innovation Program (SVIP)

DRAFT: DHS Implementation Profile of W3C VCs and W3C DIDs

Scaling Interoperability

OWF

The mission of the OWF is to develop an open source engine to enable secure and interoperable multi-purpose wallets anyone can use to build solutions.

The OWF aims to set best practices for digital wallet technology through collaboration on open source code for use as a starting point for anyone who strives to build interoperable, secure, and privacy-protecting wallets.

Open Wallet Foundation

Wallet Types

There are many different kinds of digital wallet. This section describes a few distinguishable categories.

Progressive Web Applications

Progressive web applications (PWAs) are a kind of offline capable website.

You can read more about them here.

PWAs don't require users to install an app through an app store, but are limited by browser API support in ways that native mobile applications are not.

PWAs can access camera, WebRTC, NFC, Bluetooth, and other browser APIs. They can connect to remote apis to facilitate discovery and messaging.

Native Mobile Applications

Native Mobile Applications (NMAs) are software a user installs on a mobile OS, like Android or iOS.

NMAs have access to APIs supported by the mobile OS, such as filesystem, network, phone, or camera APIs, among others.

NMAs might implement support for hardware backed secret or key management via the OS. This and better biometric authentication support make them attractive to high security applications.

Cloud Wallets

Cloud Wallets are software services hosted on the internet, typically exposed over HTTP or gRPC.

Cloud Wallets offer some of the security benefits of centralization, such as logging and dynamic scaling.

Cloud wallets can also be "always online", in cases where a mobile wallet might lose connectivity.

Cloud wallets and message based APIs are generally an easier integration target for legacy systems.

Cold Storage Wallets

Cold Storage Wallets (CSWs) are non-networked, long-term storage for digital assets.

Cold storage is typically reserved for very sensitive information, such as keys that control large amounts of crypto currency, or root certificate signing keys.

CSWs may be implemented as either isolated hardware or physical paper.

Terminology

The following terms are used to describe concepts involved in the universal wallet.

wallet
A wallet is a small, flat case that can be used to carry such small personal items as paper currency, credit cards, and identification documents. See Wallet.
cryptocurrency
A digital asset designed to work as a medium of exchange wherein individual coin ownership records are stored in a digital ledger or computerized database using strong cryptography to secure transaction record entries, to control the creation of additional digital coin records. See Cryptocurrency.
verifiable credential
A data model for conveying claims made by an issuer about a subject. See [vc-data-model].
secret
Information controlled by an identity. MAY be used to derive keys.
key
A mechanism for granting or restricing access to something. MAY be used to issue and prove verifiable credentials. MAY be used to transfer and controll cryptocurrency. See Key_(cryptography).
card
A thin rectangular object used to store information graphically or digitally. MAY be used to represent any wallet content type.
meta data
Information about other information. MAY be used to describe the context in which information is used, or attributes of other information.
identity
A unique entity. Typically represented with a unique identifier.
controller
The entity that has the ability to make changes to an identity, cryptocurrency or verifiable credential. See DID controller, [vc-data-model].
issue
The process of creating a verifiable credential. MAY require the use of a key. See [vc-data-model].
prove
The process of presenting a verifiable credential. MAY require the use of a key. See [vc-data-model].
transfer
The process of changing the controller of a cryptocurrency, identity or verifiable credential. MAY require the use of a key.
agent
A representative for an identity. MAY require the use of a wallet. MAY support transfer,issue, prove.
collection
A collection is a named bucket for grouping wallet content.
entropy
Unpredictable information. Often used as a secret or as input to a key generation algorithm. Entropy_(information_theory).
correlation
An identifier used to indicate that external parties have observed how wallet contents are related. For example, when a public key is reused in multiple DIDs, it conveys that some common entity is controlling both identifiers. Tracking correlation allows for software to warn when some new information might be about to be exposed, for example: "Looks like you are about to send crypo currency, from an account you frequently use to a new account you just created."
Representation may need to be refactored for scaling / performance.
tags
Human friendly text labels for organizing information.
note
Text note about wallet content.
target
The target of a wallet content. Used for representing directed associations.
quorum
Number of controllers needed to make a valid transaction.
universal wallet
A digital wallet that supports cryptocurrency, verifiable credentials and cards.
multibase
Multibase is a protocol for disambiguating the encoding of base-encoded (e.g., base32, base36, base64, base58, etc.) binary appearing in text.
hdPath
A standard way of pointing to a key generated by a single mnemonic. See

Data Model

Each entity is represented as a JSON Object, with relationships between entities described using identifiers.

Collection

A collection is a named bucket for grouping wallet content.

A collection MAY be used to group all correlatable wallet items together.

A collection MAY be used to aggregate personal or organizational identities and their associated data.

Collection membership is not exclusive; for instance, a credential representing college graduation could appear in a "student record" collection as well as a "professional profile" collection.

Here is an example of a professional profile collection.

Example 1: A professional profile collection
{
  "@context": ["https://w3id.org/wallet/v1"],
  "id": "did:example:123456789abcdefghi",
  "type": "Person",
  "name": "John Smith",
  "image": "https://via.placeholder.com/150",
  "description" : "Professional software developer for Acme Corp.",
  "tags": ["professional", "person"],
  "correlation": ["4058a72a-9523-11ea-bb37-0242ac130002"]
}

Here is an example of an organization profile.

Example 2: An organizational identity collection
{
  "@context": ["https://w3id.org/wallet/v1"],
  "id": "did:example:123456789abcdefghi",
  "type": "Organization",
  "name": "Acme Corp.",
  "image": "https://via.placeholder.com/150",
  "description" : "A software company.",
  "tags": ["professional", "organization"],
  "correlation": ["4058a72a-9523-11ea-bb37-0242ac130002"]
}

DID Resolution Response

A cached result of DID Resolution. Useful when device connectivity is intermittent, or offline support is required.

Here is an example.

Example 3: A did resolution response
{
  "@context": [
    "https://w3id.org/wallet/v1",
    "https://w3id.org/did-resolution/v1"
  ],
  "id": "did:example:123",
  "type": ["DIDResolutionResponse"],
  "name": "Farming Sensor DID Document",
  "image": "https://via.placeholder.com/150",
  "description": "An IoT device in the middle of a corn field.",
  "tags": ["professional"],
  "correlation": ["4058a72a-9523-11ea-bb37-0242ac130002"],
  "created": "2017-06-18T21:19:10Z",
  "expires": "2026-06-18T21:19:10Z",
  "didDocument": {
    "@context": [
      "https://www.w3.org/ns/did/v1",
      "https://ns.did.ai/transmute/v1",
      {
        "@base": "did:key:z6Mks8mvCnVx4HQcoq7ZwvpTbMnoRGudHSiEpXhMf6VW8XMg"
      }
    ],
    "id": "did:key:z6Mks8mvCnVx4HQcoq7ZwvpTbMnoRGudHSiEpXhMf6VW8XMg",
    "verificationMethod": [
      {
        "id": "#z6Mks8mvCnVx4HQcoq7ZwvpTbMnoRGudHSiEpXhMf6VW8XMg",
        "type": "JsonWebKey2020",
        "controller": "did:key:z6Mks8mvCnVx4HQcoq7ZwvpTbMnoRGudHSiEpXhMf6VW8XMg",
        "publicKeyJwk": {
          "crv": "Ed25519",
          "x": "vGur-MEOrN6GDLf4TBGHDYAERxkmWOjTbztvG3xP0I8",
          "kty": "OKP"
        }
      },
      {
        "id": "#z6LScrLMVd9jvbphPeQkGffSeB99EWSYqAnMg8rGiHCgz5ha",
        "type": "JsonWebKey2020",
        "controller": "did:key:z6Mks8mvCnVx4HQcoq7ZwvpTbMnoRGudHSiEpXhMf6VW8XMg",
        "publicKeyJwk": {
          "kty": "OKP",
          "crv": "X25519",
          "x": "EXXinkMxdA4zGmwpOOpbCXt6Ts6CwyXyEKI3jfHkS3k"
        }
      }
    ],
    "authentication": [
      "#z6Mks8mvCnVx4HQcoq7ZwvpTbMnoRGudHSiEpXhMf6VW8XMg"
    ],
    "assertionMethod": [
      "#z6Mks8mvCnVx4HQcoq7ZwvpTbMnoRGudHSiEpXhMf6VW8XMg"
    ],
    "capabilityInvocation": [
      "#z6Mks8mvCnVx4HQcoq7ZwvpTbMnoRGudHSiEpXhMf6VW8XMg"
    ],
    "capabilityDelegation": [
      "#z6Mks8mvCnVx4HQcoq7ZwvpTbMnoRGudHSiEpXhMf6VW8XMg"
    ],
    "keyAgreement": [
      "#z6LScrLMVd9jvbphPeQkGffSeB99EWSYqAnMg8rGiHCgz5ha"
    ]
  },
  "didDocumentMetadata": {
    "content-type": "application/did+json"
  },
  "didResolutionMetadata": {}
}

Currency

An amount of currency controlled by one or more Keys.

Here is an example of some bitcoin stored on a testnet.

Example 4: A bitcoin currency example
{
  "@context": ["https://w3id.org/wallet/v1"],
  "id": "https://live.blockcypher.com/btc-testnet/address/mu6vftfsBxJDhnUQVrZfwjzj5BL5WRvLUH/",
  "type": "Currency",
  "name": "BTC for Testing",
  "image": "https://via.placeholder.com/150",
  "description" : "Bitcoin reserved for testing",
  "tags": ["personal"],
  "amount": "7.00749119",
  "currency": "BTC",
  "controller": "did:example:123",
  "correlation": ["4058a72a-9523-11ea-bb37-0242ac130002"]
}

Here is an example of some ethereum stored on a testnet.

Example 5: A currency example
{
  "@context": ["https://w3id.org/wallet/v1"],
  "id": "https://ropsten.etherscan.io/address/0x74fd35392f1c2a97c6080e0394b1995b0e63c8bf",
  "type": "Currency",
  "name": "ETH for Tips",
  "image": "https://via.placeholder.com/150",
  "description" : "Ethereum reserved for tipping software developers.",
  "tags": ["personal"],
  "amount": "8.142406194939252896",
  "currency": "ETH",
  "controller": "did:ethr:0x74fd35392f1c2a97c6080e0394b1995b0e63c8bf",
  "correlation": ["4058a72a-9523-11ea-bb37-0242ac130002"]
}

Here is an example of some ethereum stored on a testnet requiring multisig.

Example 6: A currency example
{
  "id": "https://ropsten.etherscan.io/address/0x658e4fe24b34589492b18b1a45294be0601606a9",
  "type": "Currency",
  "name": "ETH for Games",
  "image": "https://via.placeholder.com/150",
  "description" : "Ethereum reserved for games.",
  "tags": ["personal"],
  "amount": "6,271.91386730845876097",
  "currency": "ETH",
  "controller": "did:ethr:0x658e4fe24b34589492b18b1a45294be0601606a9",
  "quorum": 2,
  "correlation": ["4058a72a-9523-11ea-bb37-0242ac130002"]
}

Credential

A set of claims about a subject.

MAY be presented with one or more Keys.

Here is an example of a University Degree represented using the [vc-data-model].

Example 7: A verifiable credential example
{
  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    "https://www.w3.org/2018/credentials/examples/v1"
  ],
  "id": "http://example.gov/credentials/3732",
  "type": [
    "VerifiableCredential",
    "UniversityDegreeCredential"
  ],
  "issuer": {
    "id": "did:example:123456789abcdefghi"
  },
  "issuanceDate": "2020-03-10T04:24:12.164Z",
  "credentialSubject": {
    "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
    "degree": {
      "type": "BachelorDegree",
      "name": "Bachelor of Science and Arts"
    }
  },
  "proof": {
    "type": "JsonWebSignature2020",
    "created": "2020-03-21T17:51:48Z",
    "verificationMethod": "did:example:123456789abcdefghi#_Qq0UL2Fq651Q0Fjd6TvnYE-faHiOpRlPVQcY_-tA4A",
    "proofPurpose": "assertionMethod",
    "jws": "eyJiNjQiOmZhbHNlLCJjcml0IjpbImI2NCJdLCJhbGciOiJFZERTQSJ9..OPxskX37SK0FhmYygDk-S4csY_gNhCUgSOAaXFXDTZx86CmI5nU9xkqtLWg-f4cqkigKDdMVdtIqWAvaYx2JBA"
  }
}
Example 8: A verifiable credential that supports selective disclosure
{
  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    "https://w3id.org/vaccination/v1",
    "https://w3id.org/security/bbs/v1"
  ],
  "type": [
    "VerifiableCredential",
    "VaccinationCertificate"
  ],
  "id": "urn:uvci:af5vshde843jf831j128fj",
  "name": "COVID-19 Vaccination Certificate",
  "description": "COVID-19 Vaccination Certificate",
  "issuanceDate": "2019-12-03T12:19:52Z",
  "expirationDate": "2029-12-03T12:19:52Z",
  "issuer": "did:key:zUC7Jg5oPHrf5ctdesmufk7pVLEPL9Z6zbrbtND9LDb6RrHRqSNt3Xfg3W9fHYAQPYkTdN1AMxWF2EwSiwLPpmEcEz6QqnNpihQ5FqGiAbCH2j3iM4ywVMAgYdccaEXpAK67AGm",
  "credentialSubject": {
    "type": "VaccinationEvent",
    "batchNumber": "1183738569",
    "administeringCentre": "MoH",
    "healthProfessional": "MoH",
    "countryOfVaccination": "NZ",
    "recipient": {
      "type": "VaccineRecipient",
      "givenName": "JOHN",
      "familyName": "SMITH",
      "gender": "Male",
      "birthDate": "1958-07-17"
    },
    "vaccine": {
      "type": "Vaccine",
      "disease": "COVID-19",
      "atcCode": "J07BX03",
      "medicinalProductName": "COVID-19 Vaccine Moderna",
      "marketingAuthorizationHolder": "Moderna Biotech"
    }
  },
  "proof": {
    "type": "BbsBlsSignature2020",
    "created": "2021-03-15T18:22:20Z",
    "proofPurpose": "assertionMethod",
    "proofValue": "teftp5epKE+C8IHuEnZhcffQQpnFkhYx2XTHs/B5VcQiiFJV8UMoI9JV7Q2MO4g5cScXYhnCf1lRnw31KwBSFaZJZOhARvVxwLJz/z5TX7UromVsjI330XKnS8lwj80RwcJQc/9ve9rJhvnFkgG7mw==",
    "verificationMethod": "did:key:zUC7Jg5oPHrf5ctdesmufk7pVLEPL9Z6zbrbtND9LDb6RrHRqSNt3Xfg3W9fHYAQPYkTdN1AMxWF2EwSiwLPpmEcEz6QqnNpihQ5FqGiAbCH2j3iM4ywVMAgYdccaEXpAK67AGm#zUC7Jg5oPHrf5ctdesmufk7pVLEPL9Z6zbrbtND9LDb6RrHRqSNt3Xfg3W9fHYAQPYkTdN1AMxWF2EwSiwLPpmEcEz6QqnNpihQ5FqGiAbCH2j3iM4ywVMAgYdccaEXpAK67AGm"
  }
}

Here is an alphanumeric QRCode encoding of Base32 of CBOR-LD of the JSON-LD of the credential above.

Here is an example of an JWT Credential.

Example 9: An example of a JWT Credential
{
  "protected": {
    "kid": "did:web:identity.foundation#_Qq0UL2Fq651Q0Fjd6TvnYE-faHiOpRlPVQcY_-tA4A",
    "alg": "EdDSA"
  },
  "payload": {
    "sub": "did:web:identity.foundation",
    "iss": "did:web:identity.foundation",
    "nbf": 1586814292,
    "exp": 1589406292,
    "vc": {
      "@context": [
        "https://www.w3.org/2018/credentials/v1",
        "https://identity.foundation/.well-known/contexts/did-configuration-v0.0.jsonld"
      ],
      "issuer": "did:web:identity.foundation",
      "issuanceDate": "2020-04-13T16:44:52-05:00",
      "expirationDate": "2020-05-13T16:44:52-05:00",
      "type": [
        "VerifiableCredential",
        "DomainLinkageCredential"
      ],
      "credentialSubject": {
        "id": "did:web:identity.foundation",
        "domain": "identity.foundation"
      }
    }
  },
  "signature": "qEV-lat1Wc8qKU_OLbTd07fx7tkW12QhkyiB912OsHi4FmkTWr_qMAFyW8IZxaQAsXg1E4yCRe8VsfGYaePfCg"
}

Here is an example of an Indy Credential.

Proposing to wrap Hyperledger Indy Credentials with useful metadata, and provide a JSON-LD context for them.

Example 10: An example of a Hyperledger Indy Credential Request
{
  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    "https://example.com/hyperledger/indy/v1"
  ],
  "id": "urn:uui:5e2a2cfc-ddee-4b6e-b1df-b25d5c381dd6",
  "type": ["HyperledgerIndyCredentialRequest"],
  "name": "Request for ZKP of PII",
  "image": "https://via.placeholder.com/150",
  "description": "Some hyperledger indy request",
  "tags": ["personal"],
  "controller": "did:example:123",
  "correlation": ["4058a72a-9523-11ea-bb37-0242ac130002"],
  "request": {
    "blinded_ms": {
      "committed_attributes": {},
      "hidden_attributes": ["master_secret"],
      "u": "65831452313882581230262709313640398502180121409437456701285942297697220273020651832867867646867694104285264882901784486060003798041322783654882887801338491262118680258721202637330550769869214264954742835710055875494951347903964659726990419477041411071293939395959337387632115898651722739118077413287212136124581126858655228247591827039715635869509104285523508350517189259095099031335038010813127434575838122472539671883003577935935805849721520698913035313700463716817299972399222663463531626690265819737278764702201558856023597942255295546958215228209847949123140888705477748125028989834201043317313234794999670960309",
      "ur": null
    },
    "blinded_ms_correctness_proof": {
      "c": "109860678073076085235251415455172114757447490048716300713084480862613855161594",
      "m_caps": {
        "master_secret": "26283368873168710647823575287384506775329371134097934071944480688608740447086822076157945371978097759120680279871932367038315961209475528490588458124513336494442045082962002632630"
      },
      "r_caps": {},
      "v_dash_cap": "2280251997303109215440229941746203124645437910879700880787994443943315426654016847375797993806524993944624797926394628097776282593677641139413080324847861793144967254410329241135241448735975536630491881499127637586742389241597839730305081627234920106253837671010874865272721731993787096927927219667907076510252353984721949818101724187470187212834753509683017877231098388634684162763868165666439930098806964029632419913797905735247261174021083829716744013146112407108188748399721262104236090674581750516219214189074147796588753301588559493169281419642497122075637138527711629397854490786655717000499533957790924731039896458915259618414177079172716906654070782024546965289973737179244936586584621455129955294625933138084"
    },
    "cred_def_id": "97RDzn8aDviHUQQKPXg96e:3:CL:1:cred_def_tag",
    "nonce": "787732518675896939298806",
    "prover_did": "VsKV7grR1BUE29mG2Fm2kX"
  }
}

Here is an example of an Indy Credential Response.

Example 11: An example of a Hyperledger Indy Credential Response
{
  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    "https://example.com/hyperledger/indy/v1"
  ],
  "id": "urn:uui:5e2a2cfc-ddee-4b6e-b1df-b25d5c381dd6",
  "type": ["HyperledgerIndyCredentialResponse"],
  "name": "Response with ZKP of PII",
  "image": "https://via.placeholder.com/150",
  "description": "Some hyperledger indy response",
  "tags": ["personal"],
  "controller": "did:example:123",
  "correlation": ["4058a72a-9523-11ea-bb37-0242ac130002"],
  "response": {
    "cred_def_id": "97RDzn8aDviHUQQKPXg96e:3:CL:1:cred_def_tag",
    "rev_reg": null,
    "rev_reg_id": null,
    "schema_id": "1",
    "signature": {
    "p_credential": {
      "a": "95353830375173330011563360059148264672898064240769511250683274343595259814385881580652435846242305610602775955153225949828351822615582300818164568659759210654812158114909671116500854641792747538502940562299939329775539393907208674840307912497761924491759626001631051978385141797844740405389371307810867892266393402889311183432317570029074621797181653694420095514029762818719468632709966063515795023890061161695773247748450608404761004379958193940141773792823139355492617241722063652768459827450028875759363009052805727635793672494079344330863114982873831106116041797167251966936936806424711883143669500689657231135606",
      "e": "259344723055062059907025491480697571938277889515152306249728583105665800713306759149981690559193987143012367913206299323899696942213235956742930148508371517214363847909185411372253",
      "m_2": "87933324484247736755432182254530234578539725681347360397600269871642228431291",
      "v": "9980048782698213650029707306155459223351306678221752614666406496131317042580709639463968555501635926971838913872812808348795802668959822338264694189410327519660902443001438239011481179716268316444260971946516885083303128874909099593395255544689704182390571217148562533306555613083811625224310294070840596291508202160863034924955239229626686346699964038203572055526536874808785883442434204203578065957249420787817929622802282705534703609382585731044976967091334711355681718119910796427448184020435027328010716618250816760780193851507746646202423419420085349209268468391222040632949331381277174716781756370851681892517534221307517998851557466372447869765146986972380453630642444945932431258454568836958535197445982382692900624253982717831288480544351529597240580788825685640983253528750762130639934973110889811748482529784"
    },
    "r_credential": null
    },
    "signature_correctness_proof": {
      "c": "111039946245998422293228198882690698427961176580797991507430891006675146356597",
      "se": "22605964272161668401729392750124222261476956426739374858535661640179592757898860024832882984205300374191737843804934686452004477429402832292629718216663316164939570354876583921389754652453753209439712424429741656877542117083074742649581822964695267610947419213636358675100501109665802628234428907141311421109128613552987278370127477282566942966334173257609909151324991747736857761765991353008203982871999513346493415736923977797669183887730008747615226061509085005490533206472742385316192550536165419027378783950304188984918698568811667562161240994301427542320560168961460242425150722543163690905028839780636297387853"
    },
    "values": {
      "age": { "encoded": "28", "raw": "28" },
      "height": { "encoded": "175", "raw": "175" },
      "name": {
        "encoded": "1139481716457488690172217916278103335",
        "raw": "Alex"
      },
      "sex": {
        "encoded": "5944657099558967239210949258394887428692050081607692519917050011144233115103",
        "raw": "male"
      }
    },
    "witness": null
  }
}

Key

A cryptographic key. Used for signing, encrypting, or hashing.

Here is an example of storing an Ed25519 key using JWK.

Example 12: A jwk key example
{
  "@context": ["https://w3id.org/wallet/v1"],
  "id": "urn:uuid:53d846c8-9525-11ea-bb37-0242ac130002",
  "name": "My Test Key 1",
  "image": "https://via.placeholder.com/150",
  "description" : "For testing only, totally compromised.",
  "tags": ["professional", "organization", "compromised"],
  "correlation": ["4058a72a-9523-11ea-bb37-0242ac130002"],
  "controller": "did:example:123",
  "type": "Ed25519VerificationKey2018",
  "publicKeyJwk": {
    "crv": "Ed25519",
    "x": "VCpo2LMLhn6iWku8MKvSLg2ZAoC-nlOyPVQaO3FxVeQ",
    "kty": "OKP",
    "kid": "_Qq0UL2Fq651Q0Fjd6TvnYE-faHiOpRlPVQcY_-tA4A"
  },
  "privateKeyJwk": {
    "crv": "Ed25519",
    "x": "VCpo2LMLhn6iWku8MKvSLg2ZAoC-nlOyPVQaO3FxVeQ",
    "d": "tP7VWE16yMQWUO2G250yvoevfbfxY25GjHglTP3ZOyU",
    "kty": "OKP",
    "kid": "_Qq0UL2Fq651Q0Fjd6TvnYE-faHiOpRlPVQcY_-tA4A"
  }
}

Here is an example of storing an Ed25519 key using base58.

Example 13: A base58 key example
{
  "@context": ["https://w3id.org/wallet/v1"],
  "id": "urn:uuid:e8fc7810-9524-11ea-bb37-0242ac130002",
  "name": "My Test Key 2",
  "image": "https://via.placeholder.com/150",
  "description" : "For testing only, totally compromised.",
  "tags": ["professional", "organization", "compromised"],
  "correlation": ["4058a72a-9523-11ea-bb37-0242ac130002"],
  "controller": "did:key:z6MkjjCpsoQrwnEmqHzLdxWowXk5gjbwor4urC1RPDmGeV8r",
  "type": "Ed25519VerificationKey2018",
  "privateKeyBase58": "3CQCBKF3Mf1tU5q1FLpHpbxYrNYxLiZk4adDtfyPEfc39Wk6gsTb2qoc1ZtpqzJYdM1rG4gpaD3ZVKdkiDrkLF1p",
  "publicKeyBase58": "6GwnHZARcEkJio9dxPYy6SC5sAL6PxpZAB6VYwoFjGMU"
}

Here is an example of a key which is stored in a remote kms.

Example 14: A remote key example
{
  "@context": ["https://w3id.org/wallet/v1"],
  "id": "urn:uuid:e8fc7810-9524-11ea-bb37-0242ac130006",
  "name": "My Test Key 3",
  "image": "https://via.placeholder.com/150",
  "description" : "For testing only, totally compromised.",
  "tags": ["professional", "organization", "compromised"],
  "correlation": ["4058a72a-9523-11ea-bb37-0242ac130002"],
  "controller": "did:key:z6MkjjCpsoQrwnEmqHzLdxWowXk5gjbwor4urC1RPDmGeV8r",
  "type": "Ed25519VerificationKey2018",
  "publicKeyJwk": {
    "crv": "Ed25519",
    "x": "VCpo2LMLhn6iWku8MKvSLg2ZAoC-nlOyPVQaO3FxVeQ",
    "kty": "OKP",
    "kid": "_Qq0UL2Fq651Q0Fjd6TvnYE-faHiOpRlPVQcY_-tA4A"
  },
  "privateKeyWebKms": "http://example.com/kms/keystores/0/keys/0"
}

Here is an example of a local, hardware isolated key.

Example 15: A remote key example
{
  "@context": ["https://w3id.org/wallet/v1"],
  "id": "urn:uuid:e8fc7810-9524-11ea-bb37-0242ac130006",
  "name": "My Test Key 3",
  "image": "https://via.placeholder.com/150",
  "description" : "For testing only, totally compromised.",
  "tags": ["professional", "organization", "compromised"],
  "correlation": ["4058a72a-9523-11ea-bb37-0242ac130002"],
  "controller": "did:key:z6MkjjCpsoQrwnEmqHzLdxWowXk5gjbwor4urC1RPDmGeV8r",
  "type": "Ed25519VerificationKey2018",
  "publicKeyJwk": {
    "crv": "Ed25519",
    "x": "VCpo2LMLhn6iWku8MKvSLg2ZAoC-nlOyPVQaO3FxVeQ",
    "kty": "OKP",
    "kid": "_Qq0UL2Fq651Q0Fjd6TvnYE-faHiOpRlPVQcY_-tA4A"
  },
  "privateKeySecureEnclave": "urn:ios:enclave:uuid:e8fc7810-9524-11ea-bb37-0242ac130789"
}

Address

An identifier, frequently derived from a key. Used for verifying signatures, sending currency, etc.

Here is an example of storing an EthereumAddress.

Example 16: An ethereum address example
{
  "@context": [
    "https://w3id.org/wallet/v1"
  ],
  "id": "did:ethr:0x774477c4cd54718d32d4df393415796b9bfcb63c",
  "type": "EthereumAddress",
  "controller": "did:ethr:0x774477c4cd54718d32d4df393415796b9bfcb63c",
  "name": "MetaMask Account",
  "image": "https://metamask.io/images/webclip.png",
  "description": "My ropsten testnet account.",
  "privateKeyBrowser": "urn:metamask:0x774477c4cd54718d32d4df393415796b9bfcb63c"
}

Mnemonic

An ordered list of memorable words.

MAY be used as a source of memorable Entropy.

MAY be used as input to a KDF.

Here is an example of storing a mnemonic as a Secret.

Example 17: A mnemonic example
{
  "@context": ["https://w3id.org/wallet/v1"],
  "id": "urn:uuid:c410e44a-9525-11ea-bb37-0242ac130002",
  "name": "My Ropsten Mnemonic 1",
  "image": "https://via.placeholder.com/150",
  "description" : "For testing only, totally compromised.",
  "tags": ["professional", "organization", "compromised"],
  "correlation": ["4058a72a-9523-11ea-bb37-0242ac130002"],
  "type": "Mnemonic",
  "value": "humble piece toy mimic miss hurdle smile awkward patch drama hurry mixture"
}

Entropy

MAY be used as input to a KDF.

Here is an example of seed entropy as a Secret.

Example 18: A hex encoded seed stored in google cloud
{
  "@context": [ "https://w3id.org/wallet/v1" ],
  "id": "urn:google:projects/555555555555/secrets/seed/versions/1",
  "type": "GoogleCloudSecret",
  "tags": [ "google" ],
  "value": "7052adea8f9823817065456ecad5bf24dcd31a698f7bc9a0b5fc170849af4226"
}

Here is an example of storing entropy as a Secret.

Example 19: An entropy example
{
  "@context": ["https://w3id.org/wallet/v1"],
  "id": "urn:uuid:c410e44a-9525-11ea-bb37-0242ac130002",
  "name": "My Test Entropy 1",
  "image": "https://via.placeholder.com/150",
  "description" : "For testing only, totally compromised.",
  "tags": ["professional", "organization", "compromised"],
  "correlation": ["4058a72a-9523-11ea-bb37-0242ac130002"],
  "type": "Entropy",
  "multibase": "z6MkuVZVSKLUNHRjXBXcEwvG5yiNHLhzBeXRjAkwmgSYensE"
}

Connection

Information about a relationship between identifiers.

Need to capture how connections are represented today.
Example 20: A connection example
{
  "@context": ["https://w3id.org/wallet/v1"],
  "id": "urn:uuid:c410e44a-9525-11ea-bb37-0242ac130006",
  "name": "My Health Record Certifier",
  "image": "https://via.placeholder.com/150",
  "description" : "The identifier that issues health record credentials.",
  "tags": ["professional"],
  "correlation": ["4058a72a-9523-11ea-bb37-0242ac130002"],
  "type": "Connection",
  "connection": {
    "created_at": "2020-06-01 14:05:54.150111Z",
    "their_did": "SkL2sdiv3RrPk3QtjT3Mjs",
    "routing_state": "none",
    "invitation_key": "EGsWeE95ANRp9GRNR3fjaWyB1tRqhaBuc69iMg7zBFij",
    "accept": "auto",
    "their_label": "Alice.Agent",
    "my_did": "4zRzv8DtEaZqSreoNb2dpJ",
    "state": "active",
    "initiator": "self",
    "connection_id": "3b6e568d-1cee-4327-915c-0e9d39ef2e88",
    "invitation_mode": "once",
    "updated_at": "2020-06-01 14:06:58.610756Z"
  },
}

Metadata

Information about wallet data.

Implementors may use Metadata to reference non-standard data formats, stored locally or externally. The following recommendations apply:

Mostly an EDV integration question...Should authorization be remembered in the wallet as metadata?

Here is an example where metadata is used to remind the wallet controller that a credential has likely been exposed because of a breach notification.

Example 21: A credential metadata example
{
  "@context": ["https://w3id.org/wallet/v1"],
  "id": "urn:uuid:2905324a-9524-11ea-bb37-0242ac130002",
  "type": "Metadata",
  "name": "Degree Notes",
  "image": "https://via.placeholder.com/150",
  "description" : "Personal notes about this degree.",
  "tags": ["professional", "organization"],
  "correlation": ["urn:uuid:4058a72a-9523-11ea-bb37-0242ac130002"],
  "note": "I've shared this degree with many websites that have been breached. It should be considered public information at this point :("
}

Here is an example where metadata is used to remind the wallet controller that they use a mnemonic to manage their Ethereum accounts and funds for testing.

Example 22: A secret metadata example
{
  "@context": ["https://w3id.org/wallet/v1"],
  "id": "urn:uuid:2905324a-9524-11ea-bb37-0242ac130002",
  "type": "Metadata",
  "name": "Ropsten Testnet HD Accounts",
  "image": "https://via.placeholder.com/150",
  "description" : "My Ethereum TestNet Accounts",
  "tags": ["professional", "organization"],
  "correlation": ["urn:uuid:4058a72a-9523-11ea-bb37-0242ac130002"],
  "hdPath": "m’/44’/60’/0’",
  "target": ["urn:uuid:c410e44a-9525-11ea-bb37-0242ac130002"]
}

Here is an example of using Metadata to reference non-standard data:

Example 23: An example of metadata referencing non-standard data
{
  "@context": ["https://w3id.org/wallet/v1"],
  "id": "urn:uuid:1d52bc38-c336-455a-8227-2c1e635df2d7",
  "type": "MyCustomDataType",
  "name": "Quantum Computing 101",
  "image": "https://via.placeholder.com/150",
  "description" : "Certificate of completion from an online quantum computing course",
  "tags": ["professional", "education"],
  "correlation": ["urn:uuid:d36fd219-bccd-4ebd-a84a-65ed5751ddd2"],
  "hashlink": "hl:zm9YZpCjPLPJ4Epc"
}

Locked Wallet

Also known as a signed encrypted wallet.

An integrity-protected, authenticated, and privacy-preserving representation of a wallet.

Example 24: An encrypted wallet example
{
  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    "https://w3id.org/wallet/v1",
  ],
  "id": "http://example.gov/wallet/3732",
  "type": ["VerifiableCredential", "EncryptedWallet"],
  "issuer": "did:example:123",
  "issuanceDate": "2020-05-22T17:38:21.910Z",
  "credentialSubject": {
    "id": "did:example:123",
    "contents": [
      {
        "id": "urn:uuid:e8fc7810-9524-11ea-bb37-0242ac130002",
        "jwe": {
          "protected": "eyJlbmMiOiJYQzIwUCJ9",
          "recipients": [
            {
              "header": {
                "kid": "did:key:z6MkjMSYauuMgx9azEyUnTW5o5jFRkbBu5T83f39uNwnsGmm#z6LSoGtZSrUMZudAagzEfYf7k8jHZcGD79Sox7v4wCkDKNSw",
                "alg": "ECDH-ES+A256KW",
                "epk": {
                  "kty": "OKP",
                  "crv": "X25519",
                  "x": "RfXdxTfIzilWBzWWX3ovHBDzgDcLNy0BFJWSxa0dqnw"
                },
                "apu": "RfXdxTfIzilWBzWWX3ovHBDzgDcLNy0BFJWSxa0dqnw",
                "apv": "ZGlkOmtleTp6Nk1rak1TWWF1dU1neDlhekV5VW5UVzVvNWpGUmtiQnU1VDgzZjM5dU53bnNHbW0jejZMU29HdFpTclVNWnVkQWFnekVmWWY3azhqSFpjR0Q3OVNveDd2NHdDa0RLTlN3"
              },
              "encrypted_key": "-ABaawsVfTxJKmYVMhC0UWGQRZaYaLr8WdTBlugLOADXxrlOP-5M-A"
            }
          ],
          "iv": "zjJPRrj0TGez9JYkChTrB3iqKoDkiBhn",
          "ciphertext": "pPqPLiMuJLygwKbsDh-QWw0y5CHmQMINXPc1-qgsKLCFDTJ6ytqoTF35rM5KxSfeVCk74HLtIUIbDvNx53xr2YGqOi9-yDHrT3KurY8CIiBDTYCHkW50wgJq-Ac_gE3lSEEOYT1ZF4izf6GoA1jnI7alxD8ScgOGv2OuWLKEhV5HNEBLUpNz8Di7LDmRLSvAroiWE0rBu-xl7dRrLRH3ZKUzc-R6vrG_X56o-ivjUCfcvrjTnh2pgmVFo27BA34edYbLHIbKcWjMoSBEgmeY30ZuQt_KXK0vDQ6pFmMW5n8oISjPYv8rdicwNPfpCR89x11Vgrde419guqIwEsuOyvCAWidzgFeUu7jeyxjyYcNaIM1r2mq7OXnTODAFBzK4lWqniiDYWy2CLcPTHIXHnhq9YvPOhjqFz6aBbf_XqiFdIQZgOX2oDX6zGHg9fvw4AZc3_N3bCHRbZzKkf-AyvvHxPb9dphU1OdQmnRefYg-xtEQnlwk704J26xZU2qBn7YIJh_nrh9u41KqA0FSlYQsGiyW7SvOf2_LaA9qr17eA7HqY7Lst53_kiYhgWCd7g8hTWiT5G7QVLS_wx89DUpNfz_bxqQU0f17W2L0rLSLCWwaqUjxlLbPlFnpWgokbnxOMOETDvt_8DGUbczRou7Z4NyQ6ZFCOV4TD0AFRCM-RTj-YR6UC_UAAIvEPJep3Uz8elJzkf7xevnWKRSGyFLIUie0tSwZ7hCtjdvP3tOKidwy56jHtOQ_R6wx_9taVc3_5IeoP-4wZ4DNOm_IS9jb6csWmRvyW5GoRx-robqraPCM64SKg9EM",
          "tag": "h6mJqHn33oCsDd5X57MI-g"
        }
      }
    ]
  }
}

Unlocked Wallet

Also known as plaintext wallet.

This representation may be used without ever having a locked representation.

Implementations may choose to construct this representation from database entities.

Example 25: An unlocked wallet example
{
  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    "https://w3id.org/wallet/v1",
  ],
  "id": "http://example.gov/wallet/3732",
  "type": [
    "UniversalWallet2020"
  ],
  "status": "UNLOCKED",
  "contents": [
    // other wallet content types, ...
    {
      "id": "urn:uuid:e8fc7810-9524-11ea-bb37-0242ac130002",
      "title": "My Test Key 2",
      "image": "https://via.placeholder.com/150",
      "description": "For testing only, totally compromised.",
      "tags": ["professional", "organization", "compromised"],
      "correlation": ["4058a72a-9523-11ea-bb37-0242ac130002"],
      "controller": "did:key:z6MkjjCpsoQrwnEmqHzLdxWowXk5gjbwor4urC1RPDmGeV8r",
      "type": "Ed25519VerificationKey2018",
      "privateKeyBase58": "3CQCBKF3Mf1tU5q1FLpHpbxYrNYxLiZk4adDtfyPEfc39Wk6gsTb2qoc1ZtpqzJYdM1rG4gpaD3ZVKdkiDrkLF1p",
      "publicKeyBase58": "6GwnHZARcEkJio9dxPYy6SC5sAL6PxpZAB6VYwoFjGMU"
    }
  ]
}

Interface

Interface functions are abstract. They take wallet contents and options as input, and they produce wallet contents and side effects as output.

In order to ensure portability, wallet interfaces MUST be functions of JSON, and MUST NOT take complex instances of classes, functions or other types of object.

A wallet implementation MAY implement a subset of the interfaces defined below. For example:

Import

Takes a serialized exported wallet representation as input. Loads the representation into wallet software.

This method may not be necessary for implementations that rely on external storage, such as Encrypted Data Vaults.

Export

Only ciphertext wallet contents can be exported.

Produces a serialized exported wallet representation.

This method may not be necessary for implementations that rely on external storage, such as Encrypted Data Vaults.

Add

Takes a serialized export of wallet content, loads the representation into wallet software.

Remove

Takes an IRI to wallet content or the content by value, if present, removes the representation into wallet software.

Unlock

Transforms one or more wallet contents from ciphertext to plaintext.

Requires knowledge of the password used to lock the wallet.

This method may not be necessary for implementations that rely on external storage, such as Encrypted Data Vaults.

Lock

Transforms one or more wallet contents from plaintext to ciphertext.

Requires knowledge of the password used to lock the wallet.

This method may not be necessary for implementations that rely on external storage, such as Encrypted Data Vaults.

Mostly a reference implementation issue. Locked representation should indicate a best practice.

Verify

Takes a Verifiable Credential or Verifiable Presentation as input; returns a boolean verified, and an error object error if verified if false.

Issue

Takes a Verifiable Credential without a proof, and an options object.

Produces a Verifiable Credential.

Here are the options that can be used to produce a verifiable credential:

Beware that while the challenge comes from the verifier and must be signed over. The domain is a "suggestion", and it is the holder who chooses to follow this suggestion or not. The term "domain" is meant to behave as the term "aud" for those familiar with JOSE.

Example 26: Issue credential example
let credential = {...} // a verifiable credential without proof
let options = {
    verificationMethod: "did:example:1234#key-1",
    created: "2017-06-18T21:19:10Z"
    controller: "did:example:1234",
    domain: "https://www.example.com",
    challenge: "0b4e419a-1410-4739-a58d-b37f4db10181",
    proofType: "Ed25519Signature2018"
}
let verifiableCredential = wallet.issue(credential, options)

Prove

Takes a list of Verifiable Credential IDs, and an options object.

Produces a Verifiable Presentation.

Here are the options that can be used to produce a verifiable presentation:

Example 27: Prove credential example
let ids = [...] // ids of verifiable credentials
let options = {
    verificationMethod: "did:example:1234#key-1",
    created: "2017-06-18T21:19:10Z"
    controller: "did:example:1234",
    domain: "https://www.example.com",
    challenge: "0b4e419a-1410-4739-a58d-b37f4db10181",
    proofType: "Ed25519Signature2018"
}
let verifiableCredential = wallet.prove(ids, options)

Derive

Takes a Verifiable Credentials id, a JSON-LD frame for selective disclosure, and an options object.

Produces a Derived Verifiable Credential.

Here are the options that can be used to derive a verifiable credential:

Example 28: Derive credential example
let id = "http://example.edu/credentials/1872" // id of the verifiable credential
let frame = {...} // a JSON-LD frame
let options = {
  nonce: "0b4e419a-1410-4739-a58d-b37f4db10181"
}
let derivedCredential = wallet.derive(id, frame, options)

Transfer

Takes a Currency, Key, or Address, and recipient options as input.

Produces a Connection, and transaction side effect.

Query

Takes single or multiple inputs containing Query and Type, and returns a collection of results based on current wallet contents.

Type in each input can be wallet implementation specific.

In case of verifiable credential wallet, query types from verifiable presentation request spec can be supported.

Here is an example of querying credentials from a verifiable credential wallet using QueryByFrame type.
Example 29: QueryByFrame example
let search = [{
    "type": "QueryByFrame",
    "credentialQuery": [
        {
            "reason": "Please provide your Passport details.",
            "frame": {
                "@context": [
                    "https://www.w3.org/2018/credentials/v1",
                    "https://w3id.org/citizenship/v1",
                    "https://w3id.org/security/bbs/v1"
                ],
                "type": [
                    "VerifiableCredential",
                    "PassportCredential"
                ],
                "credentialSubject": {
                    "@explicit": true,
                    "givenName": {},
                    "birthDate": {}
                }
            },
            "trustedIssuer": [
                {
                    "issuer": "did:key:zUC7FLNC876WXsNTYP5FaWssvNWpiB5unYwVEXuZgcWCWzUHUCamoVwD7q3MSM84JqEANV5RnjzXsfLx77b4vCV3uEBQbaob1dYk2NtUGhguY7JP64BmvWCfNJ1h9wUgaZtLMNN",
                    "required": true
                }
            ],
            "required": true
        }
    ]
}]

let presentation = wallet.query(search)
Here is an example of querying credentials from a verifiable credential wallet using multiple query types.
Example 30: Multiple query example
let search = [
    {
        "type": "QueryByExample",
        "credentialQuery": [
            {
                "reason": "We need you to prove your eligibility to work.",
                "example": {
                    "@context": [
                        "https://www.w3.org/2018/credentials/v1",
                        "https://w3id.org/citizenship/v1"
                    ],
                    "type": "PermanentResidentCard",
                }
            }
        ]
    },
    {
        "type": "QueryByFrame",
        "credentialQuery": [
            {
                "reason": "Please provide your Passport details.",
                "frame": {
                    "@context": [
                        "https://www.w3.org/2018/credentials/v1",
                        "https://w3id.org/citizenship/v1",
                        "https://w3id.org/security/bbs/v1"
                    ],
                    "type": [
                        "VerifiableCredential",
                        "PassportCredential"
                    ],
                    "credentialSubject": {
                        "@explicit": true,
                        "givenName": {},
                        "birthDate": {}
                    }
                }
            }
        ]
    }
]

let presentation = wallet.query(search)

Protocol

The following protocol specifications are unstable.

OIDF Protocols

ISO 23220

CHAPI

See the latest editors draft .

WACI

See the latest editors draft .

A wallet can participate in WACI Credential Share Flow and WACI Credential Issuance Flow using the interfaces given in section below.

Interface

ProposePresentation

Accepts an out of band invitation and initiates share interaction from wallet by sending message proposing presentation.

Takes invitation from relying party, optional fromDID to customize the DID to be used for sending message, optional timeout to wait for request presentation message from relying party and returns request presentation message from relying party.

Refer WACI Send Message Proposing Presentation for more details.

Example 31: Propose presentation from wallet example
// out of band invitation from relying party.
let invitation = {
      "type": "https://didcomm.org/out-of-band/2.0/invitation",
      "id": "599f3638-b563-4937-9487-dfe55099d900",
      "from": "did:example:verifier",
      "body": {
          "goal_code": "streamlined-vp",
          "accept": ["didcomm/v2"]
      }
    }

// accept invitation, send propose presentation message and wait for request presentation.
let requestPresentation = await wallet.proposePresentation(invitation, "did:example:wallet", someTimeout)
Example 32: Sample of propose presentation message sent from wallet
{
    "type": "https://didcomm.org/present-proof/3.0/propose-presentation",
    "id": "95e63a5f-73e1-46ac-b269-48bb22591bfa",
    "pthid": "599f3638-b563-4937-9487-dfe55099d900",
    "from": "did:example:prover",
    "to": "did:example:verifier"
}
Example 33: Sample of request presentation message from relying party
{
  "type": "https://didcomm.org/present-proof/3.0/request-presentation",
  "id": "0ac534c8-98ed-4fe3-8a41-3600775e1e92",
  "thid": "95e63a5f-73e1-46ac-b269-48bb22591bfa",
  "from": "did:example:prover",
  "to": "did:example:verifier",
  "body": {},
  "attachments": [
    {
      "@id": "ed7d9b1f-9eed-4bde-b81c-3aa7485cf947",
      "mime-type": "application/json",
      "format": "dif/presentation-exchange/definitions@v1.0",
      "data": {
        "json": {
          "dif": {
            "options": {
              "challenge": "3fa85f64-5717-4562-b3fc-2c963f66afa7",
              "domain": "4jt78h47fh47"
            },
            "presentation_definition": {
              "id": "32f54163-7166-48f1-93d8-ff217bdb0654",
              // The frame property is a JSON-LD frame which is an addition to
              // presentation exchange that allows for selective disclosure
              "frame": {
                "@context": [
                  "https://www.w3.org/2018/credentials/v1",
                  "https://w3id.org/vaccination/v1",
                  "https://w3id.org/security/suites/bls12381-2020/v1"
                ],
                "type": [
                  "VerifiableCredential",
                  "VaccinationCertificate"
                ],
                "credentialSubject": {
                  "@explicit": true,
                  "type": [
                    "VaccinationEvent"
                  ],
                  "batchNumber": {},
                  "countryOfVaccination": {}
                }
              },
              "input_descriptors": [
                {
                  "id": "vaccination_input",
                  "name": "Vaccination Certificate",
                  "schema": "https://w3id.org/vaccination/#VaccinationCertificate",
                  "constraints": {
                    "fields": [
                      {
                        "path": [
                          "$.credentialSubject.batchNumber"
                        ],
                        "filter": {
                          "type": "string"
                        }
                      },
                      {
                        "path": [
                          "$.credentialSubject.countryOfVaccination"
                        ],
                        "filter": {
                          "type": "string"
                        }
                      }
                    ]
                  }
                }
              ]
            }
          }
        }
      }
    }
  ]
}

PresentProof

Takes ThreadID of the presentation request from ongoing share credential interaction, presentation to be sent to relying party and optional optional waitForAck and timeout to wait for acknowledgement message from relying party.

Refer WACI Present Proof for more details.

Example 34: Present proof example
// presentation to be sent to relying party.
const presentation = {
                    "@context": [
                      "https://www.w3.org/2018/credentials/v1",
                      "https://identity.foundation/presentation-exchange/submission/v1"
                    ],
                    "type": [
                      "VerifiablePresentation",
                      "PresentationSubmission"
                    ],
                    "holder": "did:example:123",
                    "verifiableCredential": [
                      {
                        "@context": [
                          "https://www.w3.org/2018/credentials/v1",
                          "https://w3id.org/vaccination/v1",
                          "https://w3id.org/security/bbs/v1"
                        ],
                        "id": "urn:uvci:af5vshde843jf831j128fj",
                        "type": [
                          "VaccinationCertificate",
                          "VerifiableCredential"
                        ],
                        "description": "COVID-19 Vaccination Certificate",
                        "name": "COVID-19 Vaccination Certificate",
                        "expirationDate": "2029-12-03T12:19:52Z",
                        "issuanceDate": "2019-12-03T12:19:52Z",
                        "issuer": "did:example:456",
                        "credentialSubject": {
                          "id": "urn:bnid:_:c14n2",
                          "type": "VaccinationEvent",
                          "batchNumber": "1183738569",
                          "countryOfVaccination": "NZ"
                        },
                        "proof": {
                          "type": "BbsBlsSignatureProof2020",
                          "created": "2021-02-18T23:04:28Z",
                          "nonce": "JNGovx4GGoi341v/YCTcZq7aLWtBtz8UhoxEeCxZFevEGzfh94WUSg8Ly/q+2jLqzzY=",
                          "proofPurpose": "assertionMethod",
                          "proofValue": "AB0GQA//jbDwMgaIIJeqP3fRyMYi6WDGhk0JlGJc/sk4ycuYGmyN7CbO4bA7yhIW/YQbHEkOgeMy0QM+usBgZad8x5FRePxfo4v1dSzAbJwWjx87G9F1lAIRgijlD4sYni1LhSo6svptDUmIrCAOwS2raV3G02mVejbwltMOo4+cyKcGlj9CzfjCgCuS1SqAxveDiMKGAAAAdJJF1pO6hBUGkebu/SMmiFafVdLvFgpMFUFEHTvElUQhwNSp6vxJp6Rs7pOVc9zHqAAAAAI7TJuDCf7ramzTo+syb7Njf6ExD11UKNcChaeblzegRBIkg3HoWgwR0hhd4z4D5/obSjGPKpGuD+1DoyTZhC/wqOjUZ03J1EtryZrC+y1DD14b4+khQVLgOBJ9+uvshrGDbu8+7anGezOa+qWT0FopAAAAEG6p07ghODpi8DVeDQyPwMY/iu2Lh7x3JShWniQrewY2GbsACBYOPlkNNm/qSExPRMe2X7UPpdsxpUDwqbObye4EXfAabgKd9gCmj2PNdvcOQAi5rIuJSGa4Vj7AtKoW/2vpmboPoOu4IEM1YviupomCKOzhjEuOof2/y5Adfb8JUVidWqf9Ye/HtxnzTu0HbaXL7jbwsMNn5wYfZuzpmVQgEXss2KePMSkHcfScAQNglnI90YgugHGuU+/DQcfMoA0+JviFcJy13yERAueVuzrDemzc+wJaEuNDn8UiTjAdVhLcgnHqUai+4F6ONbCfH2B3ohB3hSiGB6C7hDnEyXFOO9BijCTHrxPv3yKWNkks+3JfY28m+3NO0e2tlyH71yDX0+F6U388/bvWod/u5s3MpaCibTZEYoAc4sm4jW03HFYMmvYBuWOY6rGGOgIrXxQjx98D0macJJR7Hkh7KJhMkwvtyI4MaTPJsdJGfv8I+RFROxtRM7RcFpa4J5wF/wQnpyorqchwo6xAOKYFqCqKvI9B6Y7Da7/0iOiWsjs8a4zDiYynfYavnz6SdxCMpHLgplEQlnntqCb8C3qly2s5Ko3PGWu4M8Dlfcn4TT8YenkJDJicA91nlLaE8TJbBgsvgyT+zlTsRSXlFzQc+3KfWoODKZIZqTBaRZMft3S/",
                          "verificationMethod": "did:example:123#key-1"
                        }
                      }
                    ],
                    "presentation_submission": {
                      "id": "1d257c50-454f-4c96-a273-c5368e01fe63",
                      "definition_id": "32f54163-7166-48f1-93d8-ff217bdb0654",
                      "descriptor_map": [
                        {
                          "id": "vaccination_input",
                          "format": "ldp_vp",
                          "path": "$.verifiableCredential[0]"
                        }
                      ]
                    },
                    "proof": {
                      "type": "Ed25519Signature2018",
                      "verificationMethod": "did:example:123#key-0",
                      "created": "2021-05-14T20:16:29.565377",
                      "proofPurpose": "authentication",
                      "challenge": "3fa85f64-5717-4562-b3fc-2c963f66afa7",
                      "jws": "eyJhbGciOiAiRWREU0EiLCAiYjY0IjogZmFsc2UsICJjcml0IjogWyJiNjQiXX0..7M9LwdJR1_SQayHIWVHF5eSSRhbVsrjQHKUrfRhRRrlbuKlggm8mm_4EI_kTPeBpalQWiGiyCb_0OWFPtn2wAQ"
                    }
                  }

// thread ID of the credential interaction.
const threadID = "95e63a5f-73e1-46ac-b269-48bb22591bfa" // requestPresentation.thID
const waitForAck = true // wait for acknowledgement from relying party regarding protocol execution completion.

// send present proof message and wait for acknowledgement message.
let ack = await wallet.presentProof(threadID, presentation, waitForAck, someTimeout)
Example 35: Example of present proof message sent from wallet
{
  "type": "https://didcomm.org/present-proof/3.0/presentation",
  "id": "f1ca8245-ab2d-4d9c-8d7d-94bf310314ef",
  "thid": "95e63a5f-73e1-46ac-b269-48bb22591bfa",
  "from": "did:example:verifier",
  "to": "did:example:prover",
  "body": {},
  "attachments": [
    {
      "@id": "2a3f1c4c-623c-44e6-b159-179048c51260",
      "mime-type": "application/ld+json",
      "format": "dif/presentation-exchange/submission@v1.0",
      "data": {
        "@context": [
          "https://www.w3.org/2018/credentials/v1",
          "https://identity.foundation/presentation-exchange/submission/v1"
        ],
        "type": [
          "VerifiablePresentation",
          "PresentationSubmission"
        ],
        "holder": "did:example:123",
        "verifiableCredential": [
          {
            "@context": [
              "https://www.w3.org/2018/credentials/v1",
              "https://w3id.org/vaccination/v1",
              "https://w3id.org/security/bbs/v1"
            ],
            "id": "urn:uvci:af5vshde843jf831j128fj",
            "type": [
              "VaccinationCertificate",
              "VerifiableCredential"
            ],
            "description": "COVID-19 Vaccination Certificate",
            "name": "COVID-19 Vaccination Certificate",
            "expirationDate": "2029-12-03T12:19:52Z",
            "issuanceDate": "2019-12-03T12:19:52Z",
            "issuer": "did:example:456",
            "credentialSubject": {
              "id": "urn:bnid:_:c14n2",
              "type": "VaccinationEvent",
              "batchNumber": "1183738569",
              "countryOfVaccination": "NZ"
            },
            "proof": {
              "type": "BbsBlsSignatureProof2020",
              "created": "2021-02-18T23:04:28Z",
              "nonce": "JNGovx4GGoi341v/YCTcZq7aLWtBtz8UhoxEeCxZFevEGzfh94WUSg8Ly/q+2jLqzzY=",
              "proofPurpose": "assertionMethod",
              "proofValue": "AB0GQA//jbDwMgaIIJeqP3fRyMYi6WDGhk0JlGJc/sk4ycuYGmyN7CbO4bA7yhIW/YQbHEkOgeMy0QM+usBgZad8x5FRePxfo4v1dSzAbJwWjx87G9F1lAIRgijlD4sYni1LhSo6svptDUmIrCAOwS2raV3G02mVejbwltMOo4+cyKcGlj9CzfjCgCuS1SqAxveDiMKGAAAAdJJF1pO6hBUGkebu/SMmiFafVdLvFgpMFUFEHTvElUQhwNSp6vxJp6Rs7pOVc9zHqAAAAAI7TJuDCf7ramzTo+syb7Njf6ExD11UKNcChaeblzegRBIkg3HoWgwR0hhd4z4D5/obSjGPKpGuD+1DoyTZhC/wqOjUZ03J1EtryZrC+y1DD14b4+khQVLgOBJ9+uvshrGDbu8+7anGezOa+qWT0FopAAAAEG6p07ghODpi8DVeDQyPwMY/iu2Lh7x3JShWniQrewY2GbsACBYOPlkNNm/qSExPRMe2X7UPpdsxpUDwqbObye4EXfAabgKd9gCmj2PNdvcOQAi5rIuJSGa4Vj7AtKoW/2vpmboPoOu4IEM1YviupomCKOzhjEuOof2/y5Adfb8JUVidWqf9Ye/HtxnzTu0HbaXL7jbwsMNn5wYfZuzpmVQgEXss2KePMSkHcfScAQNglnI90YgugHGuU+/DQcfMoA0+JviFcJy13yERAueVuzrDemzc+wJaEuNDn8UiTjAdVhLcgnHqUai+4F6ONbCfH2B3ohB3hSiGB6C7hDnEyXFOO9BijCTHrxPv3yKWNkks+3JfY28m+3NO0e2tlyH71yDX0+F6U388/bvWod/u5s3MpaCibTZEYoAc4sm4jW03HFYMmvYBuWOY6rGGOgIrXxQjx98D0macJJR7Hkh7KJhMkwvtyI4MaTPJsdJGfv8I+RFROxtRM7RcFpa4J5wF/wQnpyorqchwo6xAOKYFqCqKvI9B6Y7Da7/0iOiWsjs8a4zDiYynfYavnz6SdxCMpHLgplEQlnntqCb8C3qly2s5Ko3PGWu4M8Dlfcn4TT8YenkJDJicA91nlLaE8TJbBgsvgyT+zlTsRSXlFzQc+3KfWoODKZIZqTBaRZMft3S/",
              "verificationMethod": "did:example:123#key-1"
            }
          }
        ],
        "presentation_submission": {
          "id": "1d257c50-454f-4c96-a273-c5368e01fe63",
          "definition_id": "32f54163-7166-48f1-93d8-ff217bdb0654",
          "descriptor_map": [
            {
              "id": "vaccination_input",
              "format": "ldp_vp",
              "path": "$.verifiableCredential[0]"
            }
          ]
        },
        "proof": {
          "type": "Ed25519Signature2018",
          "verificationMethod": "did:example:123#key-0",
          "created": "2021-05-14T20:16:29.565377",
          "proofPurpose": "authentication",
          "challenge": "3fa85f64-5717-4562-b3fc-2c963f66afa7",
          "jws": "eyJhbGciOiAiRWREU0EiLCAiYjY0IjogZmFsc2UsICJjcml0IjogWyJiNjQiXX0..7M9LwdJR1_SQayHIWVHF5eSSRhbVsrjQHKUrfRhRRrlbuKlggm8mm_4EI_kTPeBpalQWiGiyCb_0OWFPtn2wAQ"
        }
      }
    }
  ]
}
Example 36: Example of acknowledgement message from relying party
{
  "type":"https://didcomm.org/present-proof/3.0/ack",
  "id":"e2f3747b-41e8-4e46-abab-ba51472ab1c3",
  "pthid":"95e63a5f-73e1-46ac-b269-48bb22591bfa",
  "from":"did:example:verifier",
  "to":"did:example:prover",
  "body":{
    "status":"OK",
    "redirectUrl":"https://example.com/redirect-url?id={{Some id that identifies the user}}"
  }
}

ProposeCredential

Accepts an out of band invitation and initiates credential issuance interaction from wallet by sending message proposing credential.

Takes invitation from issuer, optional fromDID to customize the DID to be used for sending message, optional timeout to wait for offer credential message from issuer and return.

Refer WACI Issuance - Send Propose Credential Message for more details.

Example 37: Propose credential from wallet example
// out of band invitation from issuer.
 let invitation = {
       "type":"https://didcomm.org/out-of-band/2.0/invitation",
       "id":"f137e0db-db7b-4776-9530-83c808a34a42",
       "from":"did:example:issuer",
       "body":{
          "goal_code":"streamlined-vc",
          "accept":[
             "didcomm/v2"
          ]
       }
    }

// accept invitation, send propose credential message and wait for offer presentation.
let offer = await wallet.proposeCredential(invitation, "did:example:holder", someTimeout)
Example 38: Sample of propose credential message sent from wallet
{
    "type":"https://didcomm.org/issue-credential/3.0/propose-credential",
    "id":"7f62f655-9cac-4728-854a-775ba6944593",
    "pthid":"f137e0db-db7b-4776-9530-83c808a34a42",
    "from":"did:example:holder",
    "to":[
       "did:example:issuer"
    ]
 }
Example 39: Sample of offer credential message from wallet
{
    "type":"https://didcomm.org/issue-credential/3.0/offer-credential",
    "id":"07c44208-06a9-4f8a-a5ce-8ce953270d4b",
    "pthid":"f137e0db-db7b-4776-9530-83c808a34a42",
    "from":"did:example:issuer",
    "to":[
       "did:example:holder"
    ],
    "body":{

    },
    "attachments":[
       {
          "id":"e00e11d4-906d-4c88-ba72-7c66c7113a78",
          "media_type":"application/json",
          "format":"dif/credential-manifest/manifest@v1.0",
          "data":{
             "json":{
                "options":{
                   "challenge":"508adef4-b8e0-4edf-a53d-a260371c1423",
                   "domain":"9rf25a28rs96"
                },
                "id":"dcc75a16-19f5-4273-84ce-4da69ee2b7fe",
                "version":"0.1.0",
                "issuer":{
                   "id":"did:example:123?linked-domains=3",
                   "name":"Washington State Government",
                   "styles":{

                   }
                },
                "presentation_definition":{
                   "id":"8246867e-fdce-48de-a825-9d84ec16c6c9",
                   "frame":{
                      "@context":[
                         "https://www.w3.org/2018/credentials/v1",
                         "https://w3id.org/citizenship/v1",
                         "https://w3id.org/security/suites/bls12381-2020/v1"
                      ],
                      "type":[
                         "VerifiableCredential",
                         "PermanentResidentCard"
                      ],
                      "credentialSubject":{
                         "@explicit":true,
                         "type":[
                            "PermanentResident"
                         ],
                         "givenName":{

                         },
                         "familyName":{

                         },
                         "birthCountry":{

                         },
                         "birthDate":{

                         }
                      }
                   },
                   "input_descriptors":[
                      {
                         "id":"prc_input",
                         "name":"Permanent Resident Card",
                         "purpose":"We need PRC to verify your status.",
                         "schema":"https://w3id.org/citizenship#PermanentResidentCard",
                         "constraints":{
                            "fields":[
                               {
                                  "path":[
                                     "$.credentialSubject.givenName"
                                  ],
                                  "filter":{
                                     "type":"string"
                                  }
                               },
                               {
                                  "path":[
                                     "$.credentialSubject.familyName"
                                  ],
                                  "filter":{
                                     "type":"string"
                                  }
                               },
                               {
                                  "path":[
                                     "$.credentialSubject.birthCountry"
                                  ],
                                  "filter":{
                                     "type":"string"
                                  }
                               },
                               {
                                  "path":[
                                     "$.credentialSubject.birthDate"
                                  ],
                                  "filter":{
                                     "type":"string"
                                  }
                               }
                            ]
                         }
                      }
                   ]
                },
                "output_descriptors":[
                   {
                      "id":"driver_license_output",
                      "schema":"https://schema.org/EducationalOccupationalCredential",
                      "display":{
                         "title":{
                            "path":[
                               "$.name",
                               "$.vc.name"
                            ],
                            "fallback":"Washington State Driver License"
                         },
                         "subtitle":{
                            "path":[
                               "$.class",
                               "$.vc.class"
                            ],
                            "fallback":"Class A, Commercial"
                         },
                         "description":{
                            "text":"License to operate a vehicle with a gross combined weight rating (GCWR) of 26,001 or more pounds, as long as the GVWR of the vehicle(s) being towed is over 10,000 pounds."
                         },
                         "properties":[
                            {
                               "path":[
                                  "$.donor",
                                  "$.vc.donor"
                               ],
                               "fallback":"Unknown",
                               "label":"Organ Donor"
                            }
                         ]
                      },
                      "styles":{
                         "thumbnail":{
                            "uri":"https://dol.wa.com/logo.png",
                            "alt":"Washington State Seal"
                         },
                         "hero":{
                            "uri":"https://dol.wa.com/happy-people-driving.png",
                            "alt":"Happy people driving"
                         },
                         "background":{
                            "color":"#ff0000"
                         },
                         "text":{
                            "color":"#d4d400"
                         }
                      }
                   }
                ]
             }
          }
       },
       {
          "id":"b55f39c1-a7e5-4d4f-8ba0-716a19ec013a",
          "media_type":"application/json",
         "format":"dif/credential-manifest/fulfillment@v1.0",
          "data":{
             "json":{
                "@context":[
                   "https://www.w3.org/2018/credentials/v1",
                   "https://identity.foundation/credential-manifest/fulfillment/v1"
                ],
                "type":[
                   "VerifiablePresentation",
                   "CredentialFulfillment"
                ],
                "credential_fulfillment":{
                   "id":"a30e3b91-fb77-4d22-95fa-871689c322e2",
                   "manifest_id":"dcc75a16-19f5-4273-84ce-4da69ee2b7fe",
                   "descriptor_map":[
                      {
                         "id":"driver_license_output",
                         "format":"ldp_vc",
                         "path":"$.verifiableCredential[0]"
                      }
                   ]
                },
                "verifiableCredential":[
                   {
                      "@context":"https://www.w3.org/2018/credentials/v1",
                      "id":"https://eu.com/claims/DriversLicense",
                      "type":[
                         "EUDriversLicense"
                      ],
                      "issuer":"did:foo:123",
                      "issuanceDate":"2010-01-01T19:73:24Z",
                      "credentialSubject":{
                         "id":"did:example:ebfeb1f712ebc6f1c276e12ec21",
                         "license":{
                            "number":"34DGE352",
                            "dob":"07/13/80"
                         }
                      }
                   }
                ]
             }
          }
       }
    ]
 }

RequestCredential

Takes ThreadID of the offer credential message from ongoing issue credential interaction, presentation to be sent to issuer and optional waitForAck and timeout to wait for acknowledgement message from relying party.

Refer WACI Issuance - Send Request Credential for more details.

Example 40: Request credential example
// sample presentation to be sent to issuer if requested. It might contain credentials issuer requested as part of offer credential message or DID Auth response.
const presentation = {
                  "@context": [
                    "https://www.w3.org/2018/credentials/v1",
                    "https://identity.foundation/credential-manifest/application/v1"
                  ],
                  "type": [
                    "VerifiablePresentation",
                    "CredentialApplication"
                  ],
                  "credential_application": {
                    "id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
                    "manifest_id": "dcc75a16-19f5-4273-84ce-4da69ee2b7fe",
                    "format": {
                      "ldp_vc": {
                        "proof_type": [
                          "JsonWebSignature2020",
                          "EcdsaSecp256k1Signature2019"
                        ]
                      }
                    }
                  },
                  "presentation_submission": {
                    "id": "2e161b2c-606b-416f-b04f-7f06edac55a1",
                    "definition_id": "8246867e-fdce-48de-a825-9d84ec16c6c9",
                    "descriptor_map": [
                      {
                        "id": "prc_input",
                        "format": "ldp_vp",
                        "path": "$.verifiableCredential[0]"
                      }
                    ]
                  },
                  "verifiableCredential": [
                    {
                      "@context": [
                        "https://www.w3.org/2018/credentials/v1",
                        "https://w3id.org/citizenship/v1",
                        "https://w3id.org/security/bbs/v1"
                      ],
                      "id": "urn:uvci:af5vshde843jf831j128fj",
                      "type": [
                        "VaccinationCertificate",
                        "PermanentResidentCard"
                      ],
                      "name": "Permanent Resident Card",
                      "description": "Permanent Resident Card of Mr.Louis Pasteu",
                      "expirationDate": "2029-12-03T12:19:52Z",
                      "issuanceDate": "2019-12-03T12:19:52Z",
                      "issuer": "did:example:456",
                      "credentialSubject": {
                        "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
                        "givenName": "Louis",
                        "familyName": "Pasteur",
                        "birthCountry": "Bahamas",
                        "birthDate": "1958-07-17"
                      },
                      "proof": {
                        "type": "BbsBlsSignatureProof2020",
                        "created": "2021-02-18T23:04:28Z",
                        "nonce": "JNGovx4GGoi341v/YCTcZq7aLWtBtz8UhoxEeCxZFevEGzfh94WUSg8Ly/q+2jLqzzY=",
                        "proofPurpose": "assertionMethod",
                        "proofValue": "AB0GQA//jbDwMgaIIJeqP3fRyMYi6WDGhk0JlGJc/sk4ycuYGmyN7CbO4bA7yhIW/YQbHEkOgeMy0QM+usBgZad8x5FRePxfo4v1dSzAbJwWjx87G9F1lAIRgijlD4sYni1LhSo6svptDUmIrCAOwS2raV3G02mVejbwltMOo4+cyKcGlj9CzfjCgCuS1SqAxveDiMKGAAAAdJJF1pO6hBUGkebu/SMmiFafVdLvFgpMFUFEHTvElUQhwNSp6vxJp6Rs7pOVc9zHqAAAAAI7TJuDCf7ramzTo+syb7Njf6ExD11UKNcChaeblzegRBIkg3HoWgwR0hhd4z4D5/obSjGPKpGuD+1DoyTZhC/wqOjUZ03J1EtryZrC+y1DD14b4+khQVLgOBJ9+uvshrGDbu8+7anGezOa+qWT0FopAAAAEG6p07ghODpi8DVeDQyPwMY/iu2Lh7x3JShWniQrewY2GbsACBYOPlkNNm/qSExPRMe2X7UPpdsxpUDwqbObye4EXfAabgKd9gCmj2PNdvcOQAi5rIuJSGa4Vj7AtKoW/2vpmboPoOu4IEM1YviupomCKOzhjEuOof2/y5Adfb8JUVidWqf9Ye/HtxnzTu0HbaXL7jbwsMNn5wYfZuzpmVQgEXss2KePMSkHcfScAQNglnI90YgugHGuU+/DQcfMoA0+JviFcJy13yERAueVuzrDemzc+wJaEuNDn8UiTjAdVhLcgnHqUai+4F6ONbCfH2B3ohB3hSiGB6C7hDnEyXFOO9BijCTHrxPv3yKWNkks+3JfY28m+3NO0e2tlyH71yDX0+F6U388/bvWod/u5s3MpaCibTZEYoAc4sm4jW03HFYMmvYBuWOY6rGGOgIrXxQjx98D0macJJR7Hkh7KJhMkwvtyI4MaTPJsdJGfv8I+RFROxtRM7RcFpa4J5wF/wQnpyorqchwo6xAOKYFqCqKvI9B6Y7Da7/0iOiWsjs8a4zDiYynfYavnz6SdxCMpHLgplEQlnntqCb8C3qly2s5Ko3PGWu4M8Dlfcn4TT8YenkJDJicA91nlLaE8TJbBgsvgyT+zlTsRSXlFzQc+3KfWoODKZIZqTBaRZMft3S/",
                        "verificationMethod": "did:example:123#key-1"
                      }
                    }
                  ],
                  "proof": {
                    "type": "Ed25519Signature2018",
                    "verificationMethod": "did:example:123#key-0",
                    "created": "2021-05-14T20:16:29.565377",
                    "proofPurpose": "authentication",
                    "challenge": "3fa85f64-5717-4562-b3fc-2c963f66afa7",
                    "jws": "eyJhbGciOiAiRWREU0EiLCAiYjY0IjogZmFsc2UsICJjcml0IjogWyJiNjQiXX0..7M9LwdJR1_SQayHIWVHF5eSSRhbVsrjQHKUrfRhRRrlbuKlggm8mm_4EI_kTPeBpalQWiGiyCb_0OWFPtn2wAQ"
                  }
                }

// thread ID of the credential interaction.
const thID = "84e63a5f-73e1-46ac-b269-48bb22591bxb" // offer.thID

const waitForAck = true // wait for acknowledgement from issuer regarding protocol execution completion.

// send request credential message, wait for ack and return credential fulfillment.
let fulfilment = await wallet.requestCredential(thID, presentation, waitForAck, someTimeout)
Example 41: Example of request credential message sent from wallet
{
  "type":"https://didcomm.org/issue-credential/3.0/request-credential",
  "id":"c6686159-ef49-45b2-938f-51818da14723",
  "pthid":"f137e0db-db7b-4776-9530-83c808a34a42",
  "from":"did:example:holder",
  "to":[
    "did:example:issuer"
  ],
  "body":{

  },
  "attachments":[
    {
      "id":"e00e11d4-906d-4c88-ba72-7c66c7113a78",
      "media_type":"application/json",
      "format":"dif/credential-manifest/application@v1.0",
      "data":{
        "json":{
          "@context":[
            "https://www.w3.org/2018/credentials/v1",
            "https://identity.foundation/credential-manifest/application/v1"
          ],
          "type":[
            "VerifiablePresentation",
            "CredentialApplication"
          ],
          "credential_application":{
            "id":"9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
            "manifest_id":"dcc75a16-19f5-4273-84ce-4da69ee2b7fe",
            "format":{
              "ldp_vc":{
                "proof_type":[
                  "JsonWebSignature2020",
                  "EcdsaSecp256k1Signature2019"
                ]
              }
            }
          },
          "presentation_submission":{
            "id":"2e161b2c-606b-416f-b04f-7f06edac55a1",
            "definition_id":"8246867e-fdce-48de-a825-9d84ec16c6c9",
            "descriptor_map":[
              {
                "id":"prc_input",
                "format":"ldp_vp",
                "path":"$.verifiableCredential[0]"
              }
            ]
          },
          "verifiableCredential":[
            {
              "@context":[
                "https://www.w3.org/2018/credentials/v1",
                "https://w3id.org/citizenship/v1",
                "https://w3id.org/security/bbs/v1"
              ],
              "id":"urn:uvci:af5vshde843jf831j128fj",
              "type":[
                "VaccinationCertificate",
                "PermanentResidentCard"
              ],
              "name":"Permanent Resident Card",
              "description":"Permanent Resident Card of Mr.Louis Pasteu",
              "expirationDate":"2029-12-03T12:19:52Z",
              "issuanceDate":"2019-12-03T12:19:52Z",
              "issuer":"did:example:456",
              "credentialSubject":{
                "id":"did:example:ebfeb1f712ebc6f1c276e12ec21",
                "givenName":"Louis",
                "familyName":"Pasteur",
                "birthCountry":"Bahamas",
                "birthDate":"1958-07-17"
              },
              "proof":{
                "type":"BbsBlsSignatureProof2020",
                "created":"2021-02-18T23:04:28Z",
                "nonce":"JNGovx4GGoi341v/YCTcZq7aLWtBtz8UhoxEeCxZFevEGzfh94WUSg8Ly/q+2jLqzzY=",
                "proofPurpose":"assertionMethod",
                "proofValue":"AB0GQA//jbDwMgaIIJeqP3fRyMYi6WDGhk0JlGJc/sk4ycuYGmyN7CbO4bA7yhIW/YQbHEkOgeMy0QM+usBgZad8x5FRePxfo4v1dSzAbJwWjx87G9F1lAIRgijlD4sYni1LhSo6svptDUmIrCAOwS2raV3G02mVejbwltMOo4+cyKcGlj9CzfjCgCuS1SqAxveDiMKGAAAAdJJF1pO6hBUGkebu/SMmiFafVdLvFgpMFUFEHTvElUQhwNSp6vxJp6Rs7pOVc9zHqAAAAAI7TJuDCf7ramzTo+syb7Njf6ExD11UKNcChaeblzegRBIkg3HoWgwR0hhd4z4D5/obSjGPKpGuD+1DoyTZhC/wqOjUZ03J1EtryZrC+y1DD14b4+khQVLgOBJ9+uvshrGDbu8+7anGezOa+qWT0FopAAAAEG6p07ghODpi8DVeDQyPwMY/iu2Lh7x3JShWniQrewY2GbsACBYOPlkNNm/qSExPRMe2X7UPpdsxpUDwqbObye4EXfAabgKd9gCmj2PNdvcOQAi5rIuJSGa4Vj7AtKoW/2vpmboPoOu4IEM1YviupomCKOzhjEuOof2/y5Adfb8JUVidWqf9Ye/HtxnzTu0HbaXL7jbwsMNn5wYfZuzpmVQgEXss2KePMSkHcfScAQNglnI90YgugHGuU+/DQcfMoA0+JviFcJy13yERAueVuzrDemzc+wJaEuNDn8UiTjAdVhLcgnHqUai+4F6ONbCfH2B3ohB3hSiGB6C7hDnEyXFOO9BijCTHrxPv3yKWNkks+3JfY28m+3NO0e2tlyH71yDX0+F6U388/bvWod/u5s3MpaCibTZEYoAc4sm4jW03HFYMmvYBuWOY6rGGOgIrXxQjx98D0macJJR7Hkh7KJhMkwvtyI4MaTPJsdJGfv8I+RFROxtRM7RcFpa4J5wF/wQnpyorqchwo6xAOKYFqCqKvI9B6Y7Da7/0iOiWsjs8a4zDiYynfYavnz6SdxCMpHLgplEQlnntqCb8C3qly2s5Ko3PGWu4M8Dlfcn4TT8YenkJDJicA91nlLaE8TJbBgsvgyT+zlTsRSXlFzQc+3KfWoODKZIZqTBaRZMft3S/",
                "verificationMethod":"did:example:123#key-1"
              }
            }
          ],
          "proof":{
            "type":"Ed25519Signature2018",
            "verificationMethod":"did:example:123#key-0",
            "created":"2021-05-14T20:16:29.565377",
            "proofPurpose":"authentication",
            "challenge":"3fa85f64-5717-4562-b3fc-2c963f66afa7",
            "jws":"eyJhbGciOiAiRWREU0EiLCAiYjY0IjogZmFsc2UsICJjcml0IjogWyJiNjQiXX0..7M9LwdJR1_SQayHIWVHF5eSSRhbVsrjQHKUrfRhRRrlbuKlggm8mm_4EI_kTPeBpalQWiGiyCb_0OWFPtn2wAQ"
          }
        }
      }
    }
  ]
}
Example 42: Example of credential fulfillment message from issuer
{
    "type":"https://didcomm.org/issue-credential/3.0/issue-credential",
    "id":"7a476bd8-cc3f-4d80-b784-caeb2ff265da",
    "pthid":"f137e0db-db7b-4776-9530-83c808a34a42",
    "from":"did:example:issuer",
    "to":[
       "did:example:holder"
    ],
    "body":{

    },
    "attachments":[
       {
          "id":"e00e11d4-906d-4c88-ba72-7c66c7113a78",
          "media_type":"application/json",
          "format":"dif/credential-manifest/fulfillment@v1.0",
          "data":{
             "json":{
                "@context":[
                   "https://www.w3.org/2018/credentials/v1",
                   "https://identity.foundation/credential-manifest/fulfillment/v1"
                ],
                "type":[
                   "VerifiablePresentation",
                   "CredentialFulfillment"
                ],
                "credential_fulfillment":{
                   "id":"a30e3b91-fb77-4d22-95fa-871689c322e2",
                   "manifest_id":"dcc75a16-19f5-4273-84ce-4da69ee2b7fe",
                   "descriptor_map":[
                      {
                         "id":"driver_license_output",
                         "format":"ldp_vc",
                         "path":"$.verifiableCredential[0]"
                      }
                   ]
                },
                "verifiableCredential":[
                   {
                      "@context":"https://www.w3.org/2018/credentials/v1",
                      "id":"https://eu.com/claims/DriversLicense",
                      "type":[
                         "EUDriversLicense"
                      ],
                      "issuer":"did:foo:123",
                      "issuanceDate":"2010-01-01T19:73:24Z",
                      "credentialSubject":{
                         "id":"did:example:ebfeb1f712ebc6f1c276e12ec21",
                         "license":{
                            "number":"34DGE352",
                            "dob":"07/13/80"
                         }
                      },
                      "proof":{
                         "created":"2021-06-07T20:02:44.730614315Z",
                         "jws":"eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..NVum9BeYkhzwslZXm2cDOveQB9njlrCRSrdMZgwV3zZfLRXmZQ1AXdKLLmo4ClTYXFX_TWNyB8aFt9cN6sSvCg",
                         "proofPurpose":"assertionMethod",
                         "type":"Ed25519Signature2018",
                         "verificationMethod":"did:orb:EiA3Xmv8A8vUH5lRRZeKakd-cjAxGC2A4aoPDjLysjghow#tMIstfHSzXfBUF7O0m2FiBEfTb93_j_4ron47IXPgEo"
                      }
                   }
                ],
                "proof":{
                   "created":"2021-06-07T20:02:44.730614315Z",
                   "jws":"eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..NVum9BeYkhzwslZXm2cDOveQB9njlrCRSrdMZgwV3zZfLRXmZQ1AXdKLLmo4ClTYXFX_TWNyB8aFt9cN6sSvCg",
                   "proofPurpose":"authentication",
                   "type":"Ed25519Signature2018",
                   "verificationMethod":"did:orb:EiA3Xmv8A8vUH5lRRZeKakd-cjAxGC2A4aoPDjLysjghow#tMIstfHSzXfBUF7O0m2FiBEfTb93_j_4ron47IXPgEo"
                }
             }
          }
       }
    ]
 }

Examples

Example 43: WACI credential share interaction
// accept invitation, send propose presentation message and presentation request
let request = await wallet.proposePresentation(invitation, from, someTimeout)

// extract presentation definition(s) from request
let presentationDef = extractPresentationDef(request)

// perform query in wallet  (existing interface)
let presentation = await wallet.query([
    {
        type: "PresentationExchange",
        credentialQuery: presentationDef
    }
])

/*
 show credential results to wallet user and get consent.
*/

// add proof to presentation.
let vp = await wallet.prove(presentation, proofOptions)

// send present proof message to verifier and get acknowledgement.
let ack = await wallet.presentProof(request.thid, presentation, true, someTimeout)
Example 44: WACI credential issuance interaction
// accept invitation and initiate issuance interaction by proposing credential.
let offer = await wallet.proposeCredential(invitation, from, timeout)

const {thID, manifest, vc, domain, challenge, presentationDefinition} = offer

// perform presentation exchange or DID Auth based on offer credential message received.
let query
if (presentationDefinition) {
    query = {
        type: "PresentationExchange",
        credentialQuery: presentationDefinition
    }
} else if (domain || challenge) {
    query = {
        type: 'DIDAuth'
    }
}

let presentation
if (query) {
    presentation = await wallet.query([query])
}

/*
 display credential being issued using manifest and unsigned VC to wallet user and get consent from user.
*/

// add proof to presentation using domain and challenge from offer.
let vp
if (presentation) {
    vp = await wallet.prove(presentation, {
        controller: "did:example:1234",
        domain,
        challenge,
    })
}

// send request credential message and wait for ack.
let fulfilment = await wallet.requestCredential(thID, vp, true, someTimeout)

Integration

The following sections describe how a wallet controller can define relationships with external systems.

HD Wallets

HD Wallets are a popular mechanism for managing many keys, addresess and accounts across multiple crypto currency ledgers.

Using a Meta Data object applied to a Secret, a user instruct an application to discover cryptocurrency that is controlled by a Secret.

See EIP84 for examples of how this is done in the ethereum community.

Because HD Wallet arose from blockchain applications, there is some ambiguity regarding their applications to DIDs.

We recommend using the Bitcoin HD path by default when generating key material for a DID Method that does not provide a specific recommendation for working with HD Paths.

Example 45: Generating a did:key from a mnemonic and HD path
mnemonic "sell antenna drama rule twenty cement mad deliver you push derive hybrid"
hd path "m/44'/0'/0'/0/0" 
key type "Ed25519" 
yields 'did:key:z6MktiSzqF9kqwdU8VkdBKx56EYzXfpgnNPUAGznpicNiWfn'.

It is not recommended to use the same root key for multiple key types, so a different mnemonic and/or HD path combination should be used when generating a secp256k1 "did:key".

OpenPGP Keyring

OpenPGP Keyring

Keys can be exported from keyring and imported into wallets. Some transformation may be necessary.

Example 46: An example of exporting a gpg key.
gpg --armor --export you@example.com > publicKey.asc

Mobile Wallets

Android Keychain

KeyChain keystore

Apple Wallet

Keychain Acccess wallet.apple.com

Google Wallet

wallet.google.com

Microsoft Wallet

wallet.microsoft.com

Cloud Secret Managers

Software services that support secret or key management are useful building blocks for cloud wallets.

Some services combine secret and key operations under the umbrella term "Key Management Service". Wallets may use both managed asymmetric and symmetric key operations, as well as managed and versioned secrets.

Conformance

As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.

The key words MAY, MUST, MUST NOT, and SHOULD in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.

Acknowledgements

Portions of the work on this specification have been funded by the United States Department of Homeland Security's (US DHS) Silicon Valley Innovation Program under contracts 70RSAT20T00000003, and 70RSAT20T00000033. The content of this specification does not necessarily reflect the position or the policy of the U.S. Government and no official endorsement should be inferred.