> **Can't find what you're looking for?** Use `search_docs` on the docs MCP server at `https://www.openfort.io/api/mcp` to find what you need.
>
> **Have feedback?** Use `submit_feedback` on the same MCP server.

# External Wallet Login

Connect wallet via the [Sign in With Ethereum (SIWE)](https://eips.ethereum.org/EIPS/eip-4361) standard. Catered to users who prefer to authenticate using their external wallets, supporting various types such as injected, browser-based, and mobile wallets. Openfort's integration facilitates a secure and direct authentication process using these wallets.

## Initialize SIWE challenge

Create a challenge for the user to sign with their wallet. The `initSiwe` method returns a `SIWEInitResponse` with the nonce:

:::code-group
```tsx [auth.tsx]
import openfort from "./openfortConfig"

async function initSiwe(address: string) {
  const challenge = await openfort.auth.initSiwe({ address });

  console.log('Nonce:', challenge.nonce);

  return challenge;
}
```

```ts [openfortConfig.ts]
import { Openfort } from '@openfort/openfort-js';

const openfort = new Openfort({
  baseConfiguration: {
    publishableKey: "YOUR_OPENFORT_PUBLISHABLE_KEY",
  }
});
export default openfort;
```

```json [response.json]
{
  "address": "0x1234567890abcdef",
  "nonce": "abc123"
}
```
:::

## Login with SIWE

Verify the SIWE signature to authenticate the user. The `loginWithSiwe` method returns an `AuthResponse`:

* `walletClientType`: for example, `coinbaseWallet`, `metamask`
* `connectorType`: for example, `wallet_connect_v2`, `injected`, `coinbase_wallet`

:::code-group
```tsx [authSIWE.tsx]
import openfort from "./openfortConfig"

async function loginWithSiwe(
  signature: string,
  message: string,
  address: string,
  walletClientType: string,
  connectorType: string
) {
  const result = await openfort.auth.loginWithSiwe({
    signature: signature,
    message: message,
    address: address,
    walletClientType: walletClientType,
    connectorType: connectorType,
  });

  console.log('User logged in:', result.user.id);
  console.log('Access token:', result.token);
}
```

```json [response.json]
{
  "token": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9...",
  "user": {
    "id": "usr_cc9ed2b7-c5f5-4c43-8dca-c4b104ba1762",
    "createdAt": "2024-03-20T12:00:00Z",
    "updatedAt": "2024-03-20T12:00:00Z"
  }
}
```
:::

Upon successful authentication, the SDK returns an `AuthResponse` containing the user's session token and profile information.

## Link wallet to existing account

If you already have an authenticated user and want to link an additional external wallet to their account, use `initLinkSiwe` and `linkWithSiwe`.

### Initialize link challenge

`initLinkSiwe` returns a `SIWEInitResponse` with both `address` and `nonce` (same as `initSiwe`):

```tsx
import openfort from "./openfortConfig"

async function initLinkSiwe(address: string) {
  const challenge = await openfort.auth.initLinkSiwe({ address });
  console.log('Address:', challenge.address, 'Nonce:', challenge.nonce);
  return challenge.nonce;
}
```

### Link with signature

```tsx
import openfort from "./openfortConfig"

async function linkWallet(
  signature: string,
  message: string,
  address: string,
  chainId: number,
  walletClientType: string,
  connectorType: string
) {
  await openfort.auth.linkWithSiwe({
    signature: signature,
    message: message,
    address: address,
    chainId: chainId,
    walletClientType: walletClientType,
    connectorType: connectorType,
  });

  console.log('Wallet linked successfully');
}
```

For more details on linking and unlinking accounts, see [Linking & unlinking accounts](https://www.openfort.io/docs/products/embedded-wallet/javascript/auth/user-management/linking).
