Skip to main content

Verification Methods

Endpoints to manage the cryptographic keys associated with a DID. A key registered as a verification method is not operationally useful until it is associated with at least one verification relationship.

addVerificationMethod

POST /api/v1/contract/addVerificationMethod

Registers a new key in the DID.

Body

FieldTypeRequiredDescription
didstringyesDID to update.
vMethodIdstringyesID of the verification method (base64url, 43 chars). Recommended: JWK thumbprint.
publicKeyTypeenumyessecp256k1 or JsonWebKey2020.
publicKeystringyesPublic key material in the format corresponding to the type (see note).
fromstringyesEOA of the signing controller.

publicKeyType Values

The enum spec includes three values, but only two are operationally supported. publicKeyType determines the format of the publicKey field, not the curve: the actual curve is inferred from the registered material itself.

ValueSupportedExpected format in publicKeyValid curves
secp256k164 hexadecimal XY bytes (uncompressed, without JWK wrapper)secp256k1 only
JsonWebKey2020JWK serialized as JSON and hex-encodedAny valid crv contained in the JWK (e.g. secp256k1, P-256)
P-256Reserved, returns 400 UNSUPPORTED

How it is stored and resolved

The registry library (@red-isbe/did-isbe-registry) reconstructs the JWK when resolving the DID with two branches (function vmToJwk):

  1. If the stored publicKey is a serialized JWK (case JsonWebKey2020) → it is returned as is. The ellipticType that the API assigned internally is ignored because the JWK already brings its own crv.
  2. If the stored publicKey is pure 64 XY bytes (case secp256k1 or legacy material) → the curve is inferred from the ellipticType and the JWK is constructed.

This means that a secp256k1 key can be registered in two different ways:

  • Via publicKeyType: "secp256k1" — compact format, 64 XY bytes.
  • Via publicKeyType: "JsonWebKey2020" — wrapping a JWK with crv: "secp256k1". More standard for integrating with the rest of the JOSE stack.

Both resolve to a verificationMethod with type: "JsonWebKey2020" and the correct curve inside the publicKeyJwk.

publicKey Format according to type

  • secp256k1 — Uncompressed hexadecimal public key with prefix 0x04 (130 chars). Example: 0x04<X><Y>.
  • JsonWebKey2020 — JWK serialized as a JSON string and hex-encoded. The did-gen keys -c <curve> utility produces this format directly as Public Key (hex of JWK). Valid structures:
    • P-256: { "kty": "EC", "crv": "P-256", "alg": "ES256", "x": "...", "y": "..." }
    • secp256k1: { "kty": "EC", "crv": "secp256k1", "x": "...", "y": "..." }

Example

{
"did": "did:isbe:uc:z12kVar5p6bD5WCjEJcQ18Zyt8XV",
"vMethodId": "WqpsDjTHnYVNvX8qx4a1FER8NgnEBS6DjLbDVrX-Fg4",
"publicKeyType": "JsonWebKey2020",
"publicKey": "0x7b226b7479223a224543222c22637276223a22502d323536...",
"from": "0xAe0E493C67f75381b0954644836A3C16c79D0dFD"
}

Response

200 OK with the unsigned transaction.


revokeVerificationMethod

POST /api/v1/contract/revokeVerificationMethod

Marks a key as revoked. Signatures made with it before notAfter remain valid; subsequent ones do not.

Body

{
"did": "did:isbe:uc:z12kVar5p6bD5WCjEJcQ18Zyt8XV",
"vMethodId": "WqpsDjTHnYVNvX8qx4a1FER8NgnEBS6DjLbDVrX-Fg4",
"notAfter": 1774700000,
"from": "0xAe0E493C67f75381b0954644836A3C16c79D0dFD"
}
FieldTypeRequiredDescription
didstringyesAffected DID.
vMethodIdstringyesID of the key to revoke.
notAfternumberyesUnix timestamp after which the key ceases to be valid.
fromstringyesEOA of the signing controller.
Difference with expireVerificationMethod

revoke is used when there is a key compromise; expire when the key reaches the natural end of its life. Functionally both do the same, but the semantics allow verifiers to distinguish reasons.


expireVerificationMethod

POST /api/v1/contract/expireVerificationMethod

Marks a key as expired.

Body

{
"did": "did:isbe:uc:z12kVar5p6bD5WCjEJcQ18Zyt8XV",
"vMethodId": "WqpsDjTHnYVNvX8qx4a1FER8NgnEBS6DjLbDVrX-Fg4",
"notAfter": 2090221463,
"from": "0xAe0E493C67f75381b0954644836A3C16c79D0dFD"
}

The fields are identical to revokeVerificationMethod.


rollVerificationMethod

POST /api/v1/contract/rollVerificationMethod

Atomic rotation: registers a new key, schedules the expiration of the old one, and defines an overlap period.

Body

FieldTypeRequiredDescription
didstringyesAffected DID.
vMethodIdstringyesID of the new key.
publicKeyTypeenumyessecp256k1 or JsonWebKey2020.
publicKeystringyesMaterial of the new public key.
notBeforenumberyesUnix timestamp of the start of validity of the new key.
notAfternumberyesUnix timestamp of the expiration of the new key.
oldVMethodIdstringyesID of the old key to rotate.
durationnumberyesOverlap period in seconds. The duration during which both keys are valid.
fromstringyesEOA of the signing controller.

Example

{
"did": "did:isbe:uc:z12kVar5p6bD5WCjEJcQ18Zyt8XV",
"vMethodId": "<NEW_THUMBPRINT>",
"publicKeyType": "JsonWebKey2020",
"publicKey": "0x<NEW_HEX_JWK>",
"notBefore": 1774700000,
"notAfter": 2090300000,
"oldVMethodId": "<PREVIOUS_THUMBPRINT>",
"duration": 86400,
"from": "0xAe0E493C67f75381b0954644836A3C16c79D0dFD"
}

In this example, during 24 hours (86400 seconds) both keys are valid; after that time, the old one is automatically expired.

Use Cases

  • Periodic rotation of keys due to security policy.
  • Algorithm migration (unusual; check compatibility first).
  • Scheduled replacement after an event that does not yet compromise the key but makes it advisable to change it.