# Linking & unlinking accounts

Developers can use Openfort to prompt users to link additional accounts (such as a wallet, phone number, or social profile) at any point in their user journey, not just during login.

## Linking accounts

### Link email

Add an email address to an existing account. Use this to upgrade guest users or add email as a secondary authentication method:

:::code-group

```tsx [auth.tsx]
import openfort from "./openfortConfig"

async function addEmail(email: string) {
  const result = await openfort.auth.addEmail({
    email: email,
    callbackURL: 'https://your-app.com/verify-email',
  });

  console.log('Verification email sent');
}
```

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

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

export default openfort;
```

:::

### Link social accounts

Initialize an OAuth linking process. Returns the OAuth authorization URL. You can pass an optional `options` parameter to customize scopes or redirect behavior:

:::code-group

```tsx [auth.tsx]
import { OAuthProvider } from '@openfort/openfort-js';
import openfort from "./openfortConfig"

async function initLinkOAuth(provider: OAuthProvider) {
  const url = await openfort.auth.initLinkOAuth({
    provider: provider,
    redirectTo: 'https://your-app.com/auth/callback',
    options: {
      scopes: 'email profile',       // Optional: request additional OAuth scopes
      skipBrowserRedirect: false,     // Optional: prevent auto-redirect
    },
  });

  window.location.href = url;
}
```

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

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

export default openfort;
```

:::

### Link wallets

Link a wallet using SIWE. First initialize the SIWE challenge to get a nonce, then create and sign the SIWE message, and finally link with the signature:

::::steps

#### Initialize SIWE challenge

`initLinkSiwe` returns a `SIWEInitResponse` containing both the `address` and `nonce`:

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

async function initLinkSIWE(address: string) {
  const { address: verifiedAddress, nonce } = await openfort.auth.initLinkSiwe({ address });

  // Use this nonce when creating your SIWE message
  console.log('Address:', verifiedAddress, 'Nonce:', nonce);
  return nonce;
}
```

#### Link with signature

:::code-group

```tsx [auth.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');
}
```

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

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

export default openfort;
```

:::

:::

### Link phone number

Link a phone number using SMS OTP. First request the OTP, then verify:

:::code-group

```tsx [auth.tsx]
import openfort from "./openfortConfig"

async function requestPhoneOtp(phoneNumber: string) {
  await openfort.auth.requestPhoneOtp({ phoneNumber });
  console.log('OTP sent to phone');
}

async function linkPhone(phoneNumber: string, otp: string) {
  const result = await openfort.auth.linkPhoneOtp({
    phoneNumber: phoneNumber,
    otp: otp,
  });

  console.log('Phone linked:', result.user.id);
}
```

```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]
{
  "token": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9...",
  "user": {
    "id": "usr_cc9ed2b7-c5f5-4c43-8dca-c4b104ba1762",
    "createdAt": "2024-03-20T12:00:00Z",
    "updatedAt": "2024-03-20T12:00:00Z"
  }
}
```

:::

## Unlinking accounts

Allow users to unlink accounts they have previously linked.

### Unlink social accounts

Unlink an OAuth provider from the account:

:::code-group

```tsx [auth.tsx]
import { OAuthProvider } from '@openfort/openfort-js';
import openfort from "./openfortConfig"

async function unlinkOAuth(provider: OAuthProvider) {
  await openfort.auth.unlinkOAuth({ provider });

  console.log('Account unlinked');
}
```

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

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

export default openfort;
```

:::

### Unlink wallets

Unlink a wallet from the account:

:::code-group

```tsx [auth.tsx]
import openfort from "./openfortConfig"

async function unlinkWallet(address: string, chainId: number) {
  await openfort.auth.unlinkWallet({
    address: address,
    chainId: chainId,
  });

  console.log('Wallet unlinked');
}
```

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

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

export default openfort;
```

:::
