# Certificates

Canonical: https://docs.projectbabbage.com/docs/guides/wallet/certificates

Certificate creation and utilization

This page explains how WalletClient works with off-chain **signed certificates** which are verifiable statements issued by a certifier such as **CoolCert** or **SocialCert**. You will see how to issue, prove, revoke, and discover certificates from the wallet's side.

---

## Why Certificates Matter

With a certificate linked to a wallet, anyone who has your identity key and is given access to one of your certificates can verify whatever claim the certifier made about you. That opens the door to use‑cases such as:

- **Access control** – enforce subscription tiers, seat limits, API quotas.

- **Proof of fact** – confirm author identity, course completion, age, licences, etc.

- **Delegation** – allow a key to spend or act on behalf of another key under strict limits.

----------

## Certificate Anatomy

- **Certificate type** - A 32‑byte Base‑64 string that names the certificate schema. Think of it as the template for an “ID Card”, “Passport”, or “Driver’s Licence”, with every certificate of that type shares the same field keys; only the values differ.
- **Fields** - An array of Key/value claims that fill the schema. Examples: `plan: premium`, `zip: 97201`, `cool: true`.
- **Signature** - 64-byte signature created by the certifier using their public key that ensures the authenticity of the certification.

----------

## Production Certifier Services

Below are two live certifiers used in the demos. The public details for **CoolCert** are shown so you can follow the code samples. A real, trusted certifier would normally keep these values private and authenticate requests on thier own backend.

**CoolCert**

```
certifierUrl : https://prod-coolcert-921101068003.us-west1.run.app
certifier    : 02cab461076409998157f05bb90f07886380186fd3d88b99c549f21de4d2511b83
type         : AGfk/WrT1eBDXpz3mcw386Zww2HmqcIn3uY6x4Af1eo=
```

**SocialCert**

```
certifierUrl : integrated into their frontend
certifier    : `02cf6cdf466951d8dfc9e7c9367511d0007ed6fba35ed42d425cc412fd6cfd4a17`
type         : one per SocialCert schema: email / phone / X
```

_(Each service defines its own certificate types and required field names)_

----------

## Issue A Certificate Using Coolcert

The snippet below shows how to ask CoolCert for a _“cool”_ certificate. You can run it against the public CoolCert demo, but in practice, these would point to your own certification backend.

```ts
// Coolcert's server public key
const certifier = '02cab461076409998157f05bb90f07886380186fd3d88b99c549f21de4d2511b83'

// Coolcert server's certifier url
const certifierUrl = 'https://prod-coolcert-921101068003.us-west1.run.app'

// Coolcert's certificate type
const type ='AGfk/WrT1eBDXpz3mcw386Zww2HmqcIn3uY6x4Af1eo='

await wallet.acquireCertificate({
  certifier: '02cab461076409998157f05bb90f07886380186fd3d88b99c549f21de4d2511b83',
  certifierUrl: 'https://prod-coolcert-921101068003.us-west1.run.app',
  acquisitionProtocol: 'issuance',
  type: 'AGfk/WrT1eBDXpz3mcw386Zww2HmqcIn3uY6x4Af1eo=',
  fields: { cool: 'true' }
});
```

Your wallet now holds a signed CoolCert certificate that anyone can verify to see that **you are cool**.

----------

## Listing and Proving Certificates

After issuing a CoolCert certificate, Alice can list all of the certificates in her wallet and selectively prove fields to Bob. Only the specified fields become visible; everything else stays encrypted.

Alice's side:
```ts
// you can add filters for listing certificates in your wallet
const certifiers = ['0220529dc803041a83f4357864a09c717daa24397cf2f3fc3a5745ae08d30924fd'] // leave empty to search for certificates with any certifier
const types = ['AGfk/WrT1eBDXpz3mcw386Zww2HmqcIn3uY6x4Af1eo='] // leave empty to search for certificates with any type

// extract a list of the filtered certificates with encrypted fields
const { certificates } = await wallet.listCertificates({
  certifiers,
  types
});

// if you specify a single certifier and a single type, there should generally only be one specific certificate returned
const certificate = certificates[0]

// create a decryptable record of the fields for the verifier's public identity key
const { keyringForVerifier } = await wallet.proveCertificate({
  certificate, // specify the specific certificate that you want prove
  fieldsToReveal: ['cool'], // expose only this field
  verifier: bobsIDKey
})
```

Bob's side:

```ts
// receive the encrypted certificate and the keyring that was made for Bob
const fields = VerifiableCertificate.fromCertificate(
  certificate,
  keyringForVerifier
)

// decrypt the fields using Bob's wallet
const alicesCertificateFields = fields.decryptFields(bobsWallet)
console.log('Alice\'s Certificate Fields:', alicesCertificateFields)
```

----------

## Attribute Discovery (find identities by certificate fields)

WalletClient can also _search_ the blockchain for certificates that match certain field values. For example, you can locate every identity that has a SocialCert email matching yours. (You can get one at [https://socialcert.net/](https://socialcert.net/))

> **Managing trust** - In BSV Desktop you’ll find a “**Trust**” tab where you can add or remove certifier servers, set trust levels for each certificate service, and set the minimum _trust threshold_.
> WalletClient ignores any certificate whose certifier scores below that threshold, so you stay in control of which certificates you accept in these discoveries.

```ts
// locate identities that have a SocialCert email field set to your address
const { certificates, totalCertificates } = await wallet.discoverByAttributes({
  attributes: { email: 'your-email@example.com' }
});
console.log('Certificates found:', totalCertificates)

// to see who provided the certificate and the revealed fields
console.log('Certifier:', certificates[0].certifierInfo.name)
console.log('Publicly revealed fields: ', certificates[0].publiclyRevealedKeyring)
```
 
### Discover by identity key

You can also look up all of the certificates owned by a single identityKey by using `discoverByIdentityKey()`.
```
// Replace bobsIDKey with the identity key you want to inspect
const { certificates } = await wallet.discoverByIdentityKey({ identityKey: bobsIDKey });

console.log('Certificates found:', certificates.length);
certificates.forEach((c, i) => {
  console.log(`${i + 1}. Type: ${c.type} · Certifier: ${c.certifierInfo.name}`);
});
```

Each entry in `certificates` includes:

- **Encrypted** `fields` and `keyring` blobs that only the holder or someone they prove to can decrypt.

- A `publiclyRevealedKeyring` that lists fields the holder has chosen to make public.

- A `decryptedFields` object that appears _only_ when the holder has revealed fields to _you_ via `proveCertificate()`.


If you need to see the contents, ask the owner to prove the specific fields you care about just like Alice did for Bob in the earlier example.

----------

## Hosting Your Own Certifier (Overview)

If you would like to facilitate your own trusted certificates, creating a certifier backend like **CoolCert** would be a good way of doing that (see [https://github.com/p2ppsr/coolcert](https://github.com/p2ppsr/coolcert) for a reference implementation). At a high level you will:

1. Generate a _certificate type_ by Base‑64‑encoding 32 random bytes.

2. Define a fixed set of field names for that schema.

3. Publish the `certifierUrl`, your certifier’s public key, and the certificate `type` so wallets know where to send requests.

4. Expose `/issue`, `/prove`, and `/revoke` HTTP endpoints that follow the same JSON contract used by CoolCert and SocialCert.

---

There are many more ways to prove your identity and your authorization than just using Certificates. If you want another tool for identity discovery, you can turn to **[IdentityClient](https://bsv-blockchain.github.io/ts-sdk/reference/identity/#class-identityclient)** in the SDK. Its helpers let you more easily do things like parsing results into displayable formats based on common types and publishing your own certificates for discovery.

That’s all you need to manage certificates from the wallet side: issue, query, prove, revoke, and discover all while without exposing sensitive information you want to keep private.
