validateChallenge

suspend fun validateChallenge(challengeXdr: String, clientAccountId: String, clientDomainAccountId: String? = null, expectedMemo: Long? = null)

Validates a challenge transaction according to SEP-10 security requirements.

This is the MOST CRITICAL security step in SEP-10 authentication. This method performs 13 required validation checks to ensure the challenge is safe to sign.

Validation Checks:

  1. Transaction envelope type must be ENVELOPE_TYPE_TX

  2. Sequence number must be exactly 0

  3. Memo type, if present, must be MEMO_ID

  4. Memo value must match expected memo (if provided)

  5. Transaction cannot have both memo and muxed account

  6. All operations must be ManageData type

  7. First operation source must be client account

  8. First operation key must be "{serverHomeDomain} auth"

  9. Client domain operation source must match (if present)

  10. Web auth domain value must match endpoint host (if present)

  11. Time bounds must be set and current time must be within bounds

  12. Transaction must have exactly 1 signature (server's)

  13. Server signature must be valid

Why validation is critical:

  • Prevents man-in-the-middle attacks

  • Prevents transaction replay attacks

  • Ensures challenge cannot perform destructive operations

  • Verifies server authenticity

  • Protects against domain confusion attacks

Example - Validate before signing:

val challenge = webAuth.getChallenge(clientAccountId)

try {
webAuth.validateChallenge(
challengeXdr = challenge.transaction,
clientAccountId = clientAccountId
)
// Challenge is valid, safe to sign
val signed = webAuth.signTransaction(challenge.transaction, signers)
} catch (e: InvalidSignatureException) {
// CRITICAL: Server signature invalid, possible MITM attack
throw SecurityException("Server signature invalid - DO NOT sign")
} catch (e: ChallengeValidationException) {
// Other validation failure
println("Challenge validation failed: ${e.message}")
}

Parameters

challengeXdr

Base64-encoded challenge transaction XDR

clientAccountId

Expected client account ID (must match first operation source)

clientDomainAccountId

Optional expected client domain account ID (if using client domain)

expectedMemo

Optional expected memo value (must match transaction memo if provided)

Throws

If any validation check fails