Web Auth For Contracts
SEP-45 Web Authentication client for contract accounts.
Provides secure authentication for Stellar smart contract accounts (C... addresses) using a challenge-response protocol with Soroban authorization entry signing. This implements the client side of the SEP-45 specification for authenticating contract accounts with Stellar services.
SEP-45 complements SEP-10, which handles traditional Stellar accounts (G... and M... addresses). Use this class when authenticating contract accounts; use SEP-10 WebAuth for regular accounts.
SEP-45 Authentication Flow
Client requests authorization entries from the authentication server
Server generates entries with specific security requirements and signs them
Client validates the authorization entries (13 security checks)
Client signs the validated entries with their keypair(s)
Client submits the signed entries back to the server
Server verifies the signatures via contract simulation and returns a JWT token
Client uses the JWT token to authenticate subsequent API requests
The JWT token can be used to authenticate requests to SEP-6 (Deposit/Withdrawal), SEP-12 (KYC), SEP-24 (Hosted Deposit/Withdrawal), SEP-31 (Cross-Border Payments), and other Stellar services that require authentication.
Usage Patterns
High-Level API (Recommended for most use cases):
// Initialize from domain's stellar.toml
val webAuth = WebAuthForContracts.fromDomain("example.com", Network.PUBLIC)
// One-line authentication
val authToken = webAuth.jwtToken(
clientAccountId = contractId,
signers = listOf(signerKeyPair)
)
// Use token in API requests
httpClient.get("https://example.com/api/account") {
header("Authorization", "Bearer ${authToken.token}")
}Contracts Without Signature Requirements:
// Some contracts implement __check_auth without requiring signatures
val authToken = webAuth.jwtToken(
clientAccountId = contractId,
signers = emptyList() // Valid for such contracts
)Client Domain Verification (Local Signing):
val authToken = webAuth.jwtToken(
clientAccountId = contractId,
signers = listOf(signerKeyPair),
clientDomain = "wallet.mycompany.com",
clientDomainAccountKeyPair = clientDomainSigningKey
)Client Domain Verification (Remote Signing):
val signingDelegate = Sep45ClientDomainSigningDelegate { entryXdr ->
// Send to wallet backend for domain signing
val response = httpClient.post("https://backend.wallet.com/sign") {
setBody(SignRequest(entryXdr))
}
response.body<SignResponse>().signedEntry
}
val authToken = webAuth.jwtToken(
clientAccountId = contractId,
signers = listOf(signerKeyPair),
clientDomain = "wallet.mycompany.com",
clientDomainSigningDelegate = signingDelegate
)Security Considerations
Always validate the challenge before signing (done automatically in jwtToken())
Verify HTTPS is used for all communication with the authentication endpoint
Verify the server's signing key matches the stellar.toml SIGNING_KEY
Never skip validation checks (all checks are required)
Store JWT tokens securely (encrypted storage, not in logs)
Check token expiration before use
Use fromDomain to automatically discover and verify server configuration
See also:
fromDomain for automatic configuration from stellar.toml
jwtToken for the complete high-level authentication flow
validateChallenge for the security validation checks
Constructors
Properties
The authentication endpoint URL (from stellar.toml WEB_AUTH_FOR_CONTRACTS_ENDPOINT)
The home domain of the server (used in challenge validation)
The server's public signing key (from stellar.toml SIGNING_KEY, G... address)
Optional Soroban RPC URL for ledger queries (defaults based on network)
Whether to use application/x-www-form-urlencoded content type for token submission. If false, uses application/json.
The web auth contract ID (from stellar.toml WEB_AUTH_CONTRACT_ID, C... address)
Functions
Decodes authorization entries from base64 XDR.
Encodes authorization entries to base64 XDR.
Requests a challenge from the authentication server.
Performs complete SEP-45 authentication flow.
Submits signed authorization entries to obtain a JWT token.
Signs the authorization entries for the client account.
Validates the authorization entries from the challenge response.