> ## Documentation Index
> Fetch the complete documentation index at: https://developers.stellar.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Stellar Authentication

> Wallets connect to anchors using a standard way of authentication via the Stellar network defined by the [SEP-10] standard.

> [!NOTE]
>
> This guide is available on four different programming languages: Typescript, Kotlin, Flutter (Dart) and Swift. You can change the shown version on each page via the buttons above.

> [!CAUTION]
>
> **Important**
>
> Documentation for this language is currently work in progress. Some of information may not be applicable for this language, or missing. Code samples may be incomplete.

Wallets connect to anchors using a standard way of authentication via the Stellar network defined by the [SEP-10] standard.

This guide will cover all ways to use SEP-10 to authenticate with an anchor.

## Creating Authentication Key

> [!NOTE]
>
> **Custodial wallets only**

First, let's create an authentication key. While you can use the same key for authentication and sending funds, it's recommended to split the responsibilities. In your application, you will have one or more fund keypairs (keypairs for the accounts that hold funds and initiate and receive transactions) and one authentication key.

The authentication key is only used for authentication purposes and doesn't need to hold any funds. Note that you don't need to create an account for this keypair either.

Go to the [Stellar Lab] and generate a keypair. The secret key must be handled securely, because it will be used for authentication.

## Basic Authentication

Let's do a basic authentication. In this example, we will use wallet SDK to create an authentication token.

First, let's create an `anchor` object to work with the anchor you are integrating with. In this example, we will be using a reference anchor implementation with the home domain `testanchor.stellar.org`

> [tab] Kotlin
>
> ```kotlin theme={"theme":{"light":"github-light","dark":"github-dark"}}
> val anchor = wallet.anchor("https://testanchor.stellar.org")
> ```

> [tab] TypeScript
>
> ```typescript theme={"theme":{"light":"github-light","dark":"github-dark"}}
> const anchor = wallet.anchor({ homeDomain: "https://testanchor.stellar.org" });
> ```

> [tab] Flutter
>
> ```dart theme={"theme":{"light":"github-light","dark":"github-dark"}}
> final anchor = wallet.anchor("testanchor.stellar.org");
> ```

> [tab] Swift
>
> ```swift theme={"theme":{"light":"github-light","dark":"github-dark"}}
> let anchor = wallet.anchor(homeDomain: "testanchor.stellar.org")
> ```

Next, authenticate with the `authKey` created earlier:

> [tab] Kotlin
>
> ```kotlin theme={"theme":{"light":"github-light","dark":"github-dark"}}
> val authKey = SigningKeyPair.fromSecret("my secret key")
>
> suspend fun getAuthToken(): AuthToken {
>   return anchor.sep10().authenticate(authKey)
> }
> ```

> [tab] TypeScript
>
> ```typescript theme={"theme":{"light":"github-light","dark":"github-dark"}}
> const authKey = SigningKeypair.fromSecret("my secret key");
> const sep10 = await anchor.sep10();
>
> const authToken = await sep10.authenticate({ accountKp: authKey });
> ```

> [tab] Flutter
>
> ```dart theme={"theme":{"light":"github-light","dark":"github-dark"}}
> final authKey = SigningKeyPair.fromSecret("my secret key");
> final sep10 = await anchor.sep10();
>
> final authToken = await sep10.authenticate(authKey);
> ```

> [tab] Swift
>
> ```swift theme={"theme":{"light":"github-light","dark":"github-dark"}}
> let authKey = try SigningKeyPair(secretKey: "my secret key")
> let sep10 = try await anchor.sep10
>
> let authToken = try await sep10.authenticate(userKeyPair: authKey)
> ```

For non-custodial wallets, you want to use the user's private key as an `authKey`.

## Home Domain (Optional)

The home domain is the optional parameter for SEP-10 authentication, when a single auth server is shared between multiple domains. Some anchors may require you to provide this argument. The SDK automatically sets the `home_domain` parameter in all SEP-10 requests.

## Client Domain (Optional)

> [!NOTE]
>
> **Non-custodial wallets only**

> [!WARNING]
>
> Some anchors may require the `client_domain` to always be present as part of the request, even for non-custodial wallets.

Client domain is used by anchors to verify the origin of user's request (which wallet this user is using?). This is particularly useful for anchors for integrating with non-custodial wallets.

Supporting `client_domain` comes in two parts, the wallet's client and the wallet's server implementations. In this setup, we will have an extra authentication key. This key will be stored remotely on the server. Using the SEP-1 info file, the anchor will be able to query this key and verify the signature. As such, the anchor would be able to confirm that the request is coming from your wallet, belonging to wallet's `client_domain`.

### Client Side

First, let's implement the client side. In this example we will connect to a remote signer that signs transactions on the endpoint `https://demo-wallet-server.stellar.org/sign` for the client domain `demo-wallet-server.stellar.org`.

> [tab] Kotlin
>
> ```kotlin theme={"theme":{"light":"github-light","dark":"github-dark"}}
> val signer = WalletSigner.DomainSigner("https://demo-wallet-server.stellar.org/sign") {}
>
> suspend fun getAuthToken(): AuthToken {
>   return anchor
>     .sep10()
>     .authenticate(userKeyPair, signer, clientDomain = "demo-wallet-server.stellar.org")
> }
> ```

> [tab] TypeScript
>
> ```typescript theme={"theme":{"light":"github-light","dark":"github-dark"}}
> const signer = new DomainSigner(
>   "https://demo-wallet-server.stellar.org/sign",
>   {},
> );
>
> const getAuthToken = async () => {
>   return anchor.sep10().authenticate({
>     accountKp,
>     walletSigner: signer,
>     clientDomain: "demo-wallet-server.stellar.org",
>   });
> };
> ```

> [tab] Flutter
>
> ```dart theme={"theme":{"light":"github-light","dark":"github-dark"}}
> final signer = DomainSigner("https://demo-wallet-server.stellar.org/sign");
> final sep10 = await anchor.sep10();
>
> final authToken = await sep10.authenticate(userKeyPair,
>   clientDomainSigner: signer, clientDomain: "demo-wallet-server.stellar.org");
> ```

> [tab] Swift
>
> ```swift theme={"theme":{"light":"github-light","dark":"github-dark"}}
> let signer = try DomainSigner(url: "https://demo-wallet-server.stellar.org/sign")
> let sep10 = try await anchor.sep10
>
> let authToken = try await sep10.authenticate(userKeyPair: authKey,
>                                              clientDomain: "demo-wallet-server.stellar.org",
>                                              clientDomainSigner: signer)
> ```

> [!CAUTION]
>
> The demo-wallet signing endpoint is not protected for anybody to use. Your production URL must be protected, otherwise anybody could impersonate your wallet's user.

Let's add authentication with a bearer token. Simply update the request transformer:

> [tab] Kotlin
>
> ```kotlin theme={"theme":{"light":"github-light","dark":"github-dark"}}
> val signer = WalletSigner.DomainSigner("https://demo-wallet-server.stellar.org/sign") { bearerAuth("authToken") }
> ```

> [tab] TypeScript
>
> ```typescript theme={"theme":{"light":"github-light","dark":"github-dark"}}
> const signer = new DomainSigner("https://demo-wallet-server.stellar.org/sign", {
>   Authorization: `Bearer ${authToken}`,
> });
> ```

> [tab] Flutter
>
> ```dart theme={"theme":{"light":"github-light","dark":"github-dark"}}
> Map<String, String> requestHeaders = {
>   "Authorization": "Bearer $authToken",
>   "Content-Type": "application/json"
> };
>
> var signer = DomainSigner("https://demo-wallet-server.stellar.org/sign",
>   requestHeaders: requestHeaders);
> ```

> [tab] Swift
>
> ```swift theme={"theme":{"light":"github-light","dark":"github-dark"}}
> let requestHeaders = ["Authorization" : "Bearer \(authToken)"]
>
> let signer = try DomainSigner(url: "https://demo-wallet-server.stellar.org/sign",
>                               requestHeaders: requestHeaders)
> ```

> [tab] TypeScript
>
> Finally, with the approach above we define the signer and client domain per request. If you want to define it once and use it for every authentication call your application is making, you can do so via changing the configuration:
>
> ```typescript theme={"theme":{"light":"github-light","dark":"github-dark"}}
> const appCfg = new ApplicationConfiguration(
>   new DomainSigner("https://my-domain.com/sign", { ...headers }),
>   undefined,
>   "my-domain.com",
> );
> ```
>
> This is particularly useful for integrating with multiple anchors.

> [tab] Kotlin
>
> Finally, with the approach above we define the signer and client domain per request. If you want to define it once and use it for every authentication call your application is making, you can do so via changing the configuration:
>
> ```kotlin theme={"theme":{"light":"github-light","dark":"github-dark"}}
> val appCfg = ApplicationConfiguration(WalletSigner.DomainSigner("https://my-domain.com/sign"), "my-domain.com")
> ```
>
> This is particularly useful for integrating with multiple anchors.

> [tab] Swift
>
> Finally, with the approach above we define the signer and client domain per request. If you want to define it once and use it for every authentication call your application is making, you can do so via changing the configuration:
>
> ```swift theme={"theme":{"light":"github-light","dark":"github-dark"}}
> let appCfg = AppConfig(defaultSigner: try DomainSigner(url: "https://my-domain.com/sign"),
>                        defaultClientDomain: "my-domain.com")
> ```
>
> This is particularly useful for integrating with multiple anchors.

### Server Side

Next, let's implement the server side.

First, generate a new authentication key that will be used as a `client_domain` authentication key.

Next, create a `SEP-1` toml file placed under `<your domain>/.well-known/stellar.toml` with the following content:

```toml theme={"theme":{"light":"github-light","dark":"github-dark"}}
ACCOUNTS = [ "Authentication public key (address)" ]
VERSION = "0.1.0"
SIGNING_KEY = "Authentication public key (address)"
NETWORK_PASSPHRASE = "Test SDF Network ; September 2015"
```

Don't forget to change the network passphrase for Mainnet deployment.

Finally, let's add server implementation. This sample implementation uses express framework:

```javascript theme={"theme":{"light":"github-light","dark":"github-dark"}}
app.post("/sign", (req, res) => {
  const envelope_xdr = req.body.transaction;
  const network_passphrase = req.body.network_passphrase;
  const transaction = new Transaction(envelope_xdr, network_passphrase);

  if (Number.parseInt(transaction.sequence, 10) !== 0) {
    res.status(400);
    res.send("transaction sequence value must be '0'");
    return;
  }

  transaction.sign(Keypair.fromSecret(SERVER_SIGNING_KEY));

  res.set("Access-Control-Allow-Origin", "*");
  res.status(200);
  res.send({
    transaction: transaction.toEnvelope().toXDR("base64"),
    network_passphrase: network_passphrase,
  });
});
```

You can see examples of both the wallet and server implementations [here](https://github.com/stellar/typescript-wallet-sdk/tree/main/%40stellar/typescript-wallet-sdk/examples/sep10). As mentioned before, this server sample implementation doesn't have any protection against unauthorized requests, so you must add authorization checks as part of the request.

[sep-1]: https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0001.md

[sep-10]: https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0010.md

[stellar lab]: https://lab.stellar.org/
