Credential issuers, by default, sign credentials using their custodial wallet, managed by Crossmint. This means that Crossmint handles the management of the wallet used for signing, providing a default and streamlined solution for issuers.

If an issuer wants to sign credentials using a separate wallet they own, they can do so by providing a signing endpoint. This endpoint is essentially a service or URL that the issuer can set up, which Crossmint will use to access the issuer’s chosen wallet for signing credentials.

Delegated signature and encryption are not concurrently supported for the moment, so it is advised to also use delegated storage for sensitive data.

Template Creation

Upon template creation, customers can specify parameters that configure the delegatedSignature specification:

  • issuerDid: The desired issuer DID represents the entity that will be issuing the credentials.
  • endpoint: The signing endpoint is the URL or endpoint where the credential signing process takes place
  • token: The Auth token for the endpoint is a secure token used to authenticate requests to the signing endpoint. This token ensures that only authorized entities can access the signing endpoint.
{
  ...standard_template_params,
  delegatedSignature: {
    issuerDid: "did:polygon:<0xADDRESS>",
    endpoint: "string",
    token: "string"
  }
}

The credential issuance process remains unchanged, except for one crucial modification. Instead of directly calling wallet.signTypedData(payload) using Crossmint’s wallet, Crossmint sends the payload to a designated endpoint. This endpoint is responsible for wrapping the signTypedData call and performing the necessary security checks to ensure only authorized payloads are processed, preventing arbitrary or malicious data from being signed.

Request Payload

Crossmint will POST to the given endpoint with the following payload:

{
    "issuer": "did:polygon:<0xADDRESS>",
    "domain": "ethers.TypedDataDomain",
    "types": "Record<string, Array<ethers.TypedDataField>>",
    "message": "<credential_object_to_sign>",
    "token": "<auth_token>"
}

Response Format

The endpoint should return a response with the following format:

{
    "credential": "<credential_object_to_sign>",
    "issuer": "<address>",
    "signature": "string"
}

DID

The issuer’s identity is represented by a DID. The DID is a string that uniquely identifies the issuer. The easiest way to provide a DID is to send the issuer’s wallet address as DID, setting issuerDid to "did:{chain}:{address}".

Web DID

Crossmint also supports Web DID. This allows issuer’s to be identified by a domain name, setting issuerDid to "did:web:issuer.com". webDID leverages existing web domain reputation to establish trust around decentralized identities.

The issuer must have a DID Document hosted at https://issuer.com/.well-known/did.json for the webDID mapping to work properly. The DID document, among other useful information, needs to contain the “service” attribute, stating the issuer’s wallet address: The issuer’s wallet is the wallet that will be used to sign the credential and verifiers can recognize this wallet by its related webDID.

{
    "id": "did:web:myissuer.com",
    "service": [
        {
            "id": "did:web:myissuer.com#wallet",
            "type": "wallet",
            "serviceEndpoint": "chain:<0xADDRESS>"
        }
    ]
    // ... other properties like verificationMethod, authentication, etc.
}