Skip to Content
API ReferenceHandshake

Handshake API

createChallenge

Creates a challenge message with a random nonce for the trust handshake.

function createChallenge(options: { from: string }): ChallengeMessage

Parameters

ParameterTypeRequiredDescription
fromstringYesDID of the challenger (the service)

Returns

ChallengeMessage

FieldTypeDescription
type"credat:challenge"Message type identifier
noncestringBase64url-encoded 32-byte random value
fromstringThe challenger’s DID
timestampstringISO 8601 creation time

Example

import { createChallenge } from "@credat/sdk"; const challenge = createChallenge({ from: "did:web:service.com" }); // { // type: "credat:challenge", // nonce: "dG9rZW4tMTIz...", // from: "did:web:service.com", // timestamp: "2026-02-24T10:00:00.000Z" // }

presentCredentials

Creates a presentation message: the agent signs the challenge nonce and attaches its delegation credential.

function presentCredentials(options: PresentOptions): Promise<PresentationMessage>

Parameters

PresentOptions

ParameterTypeRequiredDescription
challengeChallengeMessageYesThe challenge from the service
delegationstringYesThe raw delegation token (delegation.token)
agentAgentIdentityYesThe agent’s full identity

Returns

PresentationMessage

FieldTypeDescription
type"credat:presentation"Message type identifier
delegationstringThe delegation credential (SD-JWT VC)
noncestringThe challenge nonce (echoed back)
proofstringBase64url-encoded signature of the nonce
fromstringThe agent’s DID

Example

import { presentCredentials } from "@credat/sdk"; const presentation = await presentCredentials({ challenge, delegation: delegation.token, agent, });

verifyPresentation

Verifies a complete presentation: nonce proof, agent identity, and delegation credential.

function verifyPresentation( presentation: PresentationMessage, options: VerifyPresentationOptions, ): Promise<DelegationResult>

Parameters

ParameterTypeRequiredDescription
presentationPresentationMessageYesThe presentation from the agent

VerifyPresentationOptions

ParameterTypeRequiredDefaultDescription
challengeChallengeMessageYes---The original challenge
ownerPublicKeyUint8ArrayYes---Owner’s public key
agentPublicKeyUint8ArrayYes---Agent’s public key
agentAlgorithm"ES256" | "EdDSA"Noauto-detectedAgent’s signing algorithm
challengeMaxAgeMsnumberNo300000 (5 min)Maximum age of challenge before rejection

Returns

DelegationResult --- same shape as verifyDelegation. See Delegation API.

Verification steps

  1. Nonce match --- Presentation nonce matches the challenge nonce
  2. Nonce proof --- Agent’s signature over the nonce is valid (proves identity)
  3. Delegation --- The delegation VC is valid, signed by the owner, and not expired

If any step fails, the function returns early with the relevant error.

Algorithm detection

If agentAlgorithm is not specified, it’s inferred from the public key:

  • 33 bytes -> ES256 (P-256 compressed)
  • 32 bytes -> EdDSA (Ed25519)

Example

import { verifyPresentation } from "@credat/sdk"; const result = await verifyPresentation(presentation, { challenge, ownerPublicKey: ownerKeyPair.publicKey, agentPublicKey: agent.keyPair.publicKey, }); if (result.valid) { console.log(result.agent); // Agent DID console.log(result.owner); // Owner DID console.log(result.scopes); // Granted scopes }

Errors in result

CodeMeaning
HANDSHAKE_INVALID_NONCENonce doesn’t match (replay attack or wrong challenge)
HANDSHAKE_EXPIREDChallenge has expired (older than challengeMaxAgeMs)
HANDSHAKE_VERIFICATION_FAILEDAgent’s signature over nonce is invalid
DELEGATION_SIGNATURE_INVALIDDelegation not signed by the claimed owner
DELEGATION_EXPIREDDelegation credential has expired

Message types

All three message types are exported as TypeScript types:

import type { ChallengeMessage, PresentationMessage, AckMessage, HandshakeMessage, // Union of all three } from "@credat/sdk";

AckMessage

The acknowledgment message sent after verification. This is a convenience type --- Credat does not generate it automatically.

FieldTypeDescription
type"credat:ack"Message type identifier
verifiedbooleanWhether verification succeeded
scopesstring[] | undefinedGranted scopes (if verified)
counterChallengeChallengeMessage | undefinedFor mutual authentication
delegationstring | undefinedService’s delegation (for mutual auth)
proofstring | undefinedService’s nonce proof (for mutual auth)
fromstring | undefinedService’s DID
Last updated on