> For the complete documentation index, see [llms.txt](https://fifo-docs.gitbook.io/colibri/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://fifo-docs.gitbook.io/colibri/colibri-webauth/discovery.md).

# Discovery and account routing

[WebAuth overview](/colibri/colibri-webauth/webauth.md)

## Create a client

```typescript
import { NetworkConfig } from "@colibri/core";
import { WebAuthClient } from "@colibri/webauth";

const client = await WebAuthClient.fromDomain("anchor.example.com", {
  network: NetworkConfig.TestNet(),
});
```

The network supplied by the application is authoritative. If stellar.toml or a challenge response includes a different network passphrase, authentication fails.

`fromDomain()` fetches the home domain's `stellar.toml` before a challenge is requested. `fromToml(toml, options)` accepts an already parsed Core [`StellarToml`](/colibri/colibri-core/sep1.md). Direct construction uses `new WebAuthClient({ homeDomain, signingKey, network, sep10?, sep45? })`, where [SEP-10](/colibri/colibri-webauth/sep10.md) supplies `{ endpoint }` and [SEP-45](/colibri/colibri-webauth/sep45.md) supplies `{ endpoint, contractId }`. Direct configuration means the application is responsible for the trustworthiness of that discovery data.

Construction accepts `timeout` (30,000 ms by default), `fetch`, `submissionFormat` (`json` by default or `form`), and `allowHttp` for deliberate local development. The timeout bounds both the HTTP request and consumption of its response body, not the server challenge's validity period. The challenge's own time/ledger constraints remain authoritative.

A connection that fails while reading the body raises [`WEBAUTH_RESPONSE_BODY_FAILED`](/colibri/reference/errors/webauth.md); a body that outlives the deadline raises [`WEBAUTH_TIMEOUT`](/colibri/reference/errors/webauth.md).

## Choose a path

`WebAuthClient` exposes three entry points:

* `client.authenticate(...)` routes by account type.
* `client.sep10` selects [SEP-10](/colibri/colibri-webauth/sep10.md) explicitly.
* `client.sep45` selects [SEP-45](/colibri/colibri-webauth/sep45.md) explicitly.

Automatic routing is deterministic and has no protocol fallback:

| Account | Protocol                                    | Required option | Invalid options                                                              |
| ------- | ------------------------------------------- | --------------- | ---------------------------------------------------------------------------- |
| `G...`  | [SEP-10](/colibri/colibri-webauth/sep10.md) | `signer`        | [SEP-45](/colibri/colibri-webauth/sep45.md) authorization options            |
| `M...`  | [SEP-10](/colibri/colibri-webauth/sep10.md) | `signer`        | `memo` and [SEP-45](/colibri/colibri-webauth/sep45.md) authorization options |
| `C...`  | [SEP-45](/colibri/colibri-webauth/sep45.md) | `authorize`     | `signer` and `memo`                                                          |

Inspect discovery and routing with:

```typescript
client.supports("sep10");
client.supports("sep45");
client.protocolFor(account);
```

## Client domains

Pass the client domain and its signing key:

```typescript
const jwt = await client.authenticate({
  account: keypair.publicKey(),
  signer: keypair,
  clientDomain: "wallet.example.com",
  clientDomainSigner: walletDomainKeypair,
});
```

The client domain's stellar.toml is fetched only when the server's challenge actually accepts the requested client domain.
