Multisig Wallets

Validate a signer enrollment

Confirm a pending enrollment with the 4-digit code read off the candidate's phone. Only a signer already on the wallet can validate, and the enrollment must have been challenged and revealed first.

What this catches: a candidate identity substituted between the two phones, and plain human error — the API withholds the identity of a requested enrollment precisely so the code cannot be read off a screen instead of the other phone, and the engagement–reveal keeps the short code from being ground: a wrong code burns the enrollment. What it does not catch: a signer who is themselves the attacker. One validation admits a key, so a single compromised signer can grow the set with keys they control. Raising the admission quorum and notifying every signer on each validation are tracked as hardening.

post/v1/multisig-wallets/{walletId}/signers/{signerId}/validation

Request

  • Base URL: https://api.prod.keyban.io
  • URL: https://api.prod.keyban.io/v1/multisig-wallets/{walletId}/signers/{signerId}/validation
  • Auth: one of:
    • API key in header X-Api-Key
    • bearer (a scheme the document does not define)

Path parameters

walletIdstring uuid required

The unique identifier of the multisig wallet

signerIdstring uuid required

The enrollment to validate

Request body

codestring required

Four-digit SAS read off the candidate phone and compared out of band. A wrong code burns the enrollment (status failed): the short code buys a single online guess, not an offline search.

Example request

{
  "code": "6040"
}

Response

Enrollment validated

idstring uuid required

Entity UUID

createdAtstring date-time required

Creation date (ISO 8601)

updatedAtstring date-time required

Last update date (ISO 8601)

status'requested' | 'validated' | 'active' | 'failed' required

Enrollment status: requested (address bound, awaiting a peer validation), validated (counts towards the threshold), active (in the on-chain signer set, can sign), failed (on-chain add exhausted its retries).

signerType'eoa' | 'webauthn' required

Kind of key behind this signer: eoa (20-byte secp256k1 address) or webauthn (84-byte P-256 passkey signer). Derived from the identity, never stored.

addressstring nullable

ERC-7913 identity of the signing key: a 20-byte EVM address for an eoa signer, the 84-byte verifier ‖ qx ‖ qy bytes for a webauthn one. Withheld while requested: the SAS a validator must type derives from it, so serving it here would let any client compute the code instead of reading it off the candidate's phone — the whole point of the comparison. Revealed once validated.

validatorNoncestring nullable

The challenge nonce, once a validator has challenged this enrollment. The candidate app reads it to derive the 4-digit SAS it displays; null before a challenge and after the ceremony settles.

validatedAtstring date-time nullable required

When a peer validated this enrollment. Null while requested.

Example response

{
  "status": "active",
  "user": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Jeanne Martin",
    "email": "jeanne.martin@example.com",
    "image": "https://example.com/avatar.png"
  },
  "signerType": "eoa",
  "address": "0x36bc36646e0f00e567a126e116f0d1a0dc21c810",
  "validatorNonce": "0x2222222222222222222222222222222222222222222222222222222222222222"
}

Changes

No recorded changes to this operation across all 1 revision of this API.