sendSignedChallenge

suspend fun sendSignedChallenge(signedChallengeXdr: String): AuthToken

Submits a signed challenge transaction to obtain JWT token.

This is the final step of the SEP-10 authentication flow. The signed challenge is sent to the server, which verifies the signatures and returns a JWT token.

HTTP Request:

POST {authEndpoint}
Content-Type: application/json

{
"transaction": "base64_signed_challenge_xdr"
}

Server verification:

  1. Validates transaction structure (same checks as client)

  2. Verifies time bounds are still valid

  3. Verifies client signature(s) are valid

  4. Checks signing weight meets account threshold

  5. Generates and signs JWT token

  6. Returns token in response

Example - Submit signed challenge:

val authToken = webAuth.sendSignedChallenge(signedChallengeXdr)

println("Token: ${authToken.token}")
println("Account: ${authToken.account}")
println("Expires: ${authToken.exp}")

// Use token in API requests
httpClient.get("https://example.com/api/account") {
header("Authorization", "Bearer ${authToken.token}")
}

Example - Handle submission errors:

try {
val authToken = webAuth.sendSignedChallenge(signedChallenge)
} catch (e: TokenSubmissionException) {
when {
e.message?.contains("401") == true -> {
// Signature verification failed
println("Invalid signatures or insufficient signing weight")
}
e.message?.contains("400") == true -> {
// Invalid transaction
println("Malformed transaction or expired challenge")
}
}
}

Return

AuthToken containing JWT token and parsed claims

Parameters

signedChallengeXdr

Base64-encoded signed challenge XDR

Throws

If submission fails or server returns an error