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

# Rotate Passkey Credentials Proactively with SocketFi

> Guide to proactive credential rotation — moving to a new device, upgrading a passkey, and keeping wallet access secure without account recovery.

Credential rotation lets a user replace their passkey while they still have access to the current one. It is the right choice when a user upgrades to a new phone, retires an old device, or wants to migrate their passkey to a different authenticator as a security hygiene step. Unlike account recovery — which is a reactive process triggered by a lost credential — rotation is a proactive operation that the user initiates while fully authenticated.

## Rotation vs recovery

The key difference is whether the user can still sign in:

| Situation                                 | Right flow              |
| ----------------------------------------- | ----------------------- |
| User has their current device and passkey | **Credential rotation** |
| User has lost their device or passkey     | **Account recovery**    |

Rotation is simpler and more secure than recovery because the user proves ownership directly with their existing credential. No identity verification from a third party is needed. If your users are about to get a new phone, guide them to rotate before they wipe or dispose of the old device — it's a much smoother experience than going through recovery afterward.

## What rotation changes and what it preserves

Rotation only replaces the authentication credential. Everything else stays exactly the same:

| What changes        | What is preserved                   |
| ------------------- | ----------------------------------- |
| Passkey (old → new) | Wallet address                      |
|                     | All token balances and NFTs         |
|                     | Full transaction history            |
|                     | Active DeFi positions               |
|                     | Wallet policies and spending limits |
|                     | Application integrations            |

## The rotation flow

<Steps>
  ### User authenticates with the current credential

  The user must be fully signed in before starting rotation. This proves they still control the existing passkey and ensures no one else can initiate a rotation on their behalf.

  Direct users to your security settings area to begin:

  ```typescript src/screens/SecuritySettingsScreen.tsx theme={null}
  import { useAuth } from "../auth/context";

  export function SecuritySettingsScreen() {
    const { authenticated } = useAuth();

    if (!authenticated) return null;

    return (
      <div>
        <h2>Security Settings</h2>

        <section>
          <h3>Passkey</h3>
          <p>
            Moving to a new device? Update your passkey now to make sure you
            can always access your wallet.
          </p>
          <a href="/settings/security/rotate-passkey">Update Passkey →</a>
        </section>
      </div>
    );
  }
  ```

  <Note>
    If the user is not signed in, redirect them to the login screen first. You should never allow rotation from an unauthenticated state.
  </Note>

  ### Create a new passkey on the new device

  The user generates a fresh passkey on their target device. The SocketFi SDK orchestrates the WebAuthn credential creation:

  ```typescript src/services/rotation.ts theme={null}
  import { socketfi } from "../socketfi/client";

  export async function startCredentialRotation(): Promise<{ success: boolean }> {
    // The SDK prompts the user to create a new passkey and handles
    // proof-of-possession before submitting the rotation transaction
    return socketfi.rotateCredential();
  }
  ```

  Walk the user through the device prompt with clear instructions:

  ```text theme={null}
  Step 1 of 3: Create your new passkey

  Your device will ask you to set up a new sign-in credential.
  When prompted, use Face ID, Touch ID, or your device PIN.
  This new passkey will replace your current one once the
  update is confirmed.
  ```

  ### SDK verifies proof of possession

  Before the new credential can be registered, the SocketFi SDK proves that the user genuinely controls the new passkey — not just that they know its public key. This prevents credential injection attacks.

  The proof flow happens automatically inside the SDK:

  ```text theme={null}
  Challenge issued by SocketFi
          ↓
  New passkey signs the challenge
          ↓
  Signature verified by SocketFi
          ↓
  Proof accepted
  ```

  No extra code is required from you. The SDK rejects the rotation automatically if proof fails.

  ### Current credential authorizes the rotation

  The existing passkey signs an authorization that instructs the wallet contract to accept the new credential. This is the step that makes rotation fundamentally more secure than recovery — the wallet can verify ownership directly without delegating to a third-party identity verification service.

  The wallet contract checks:

  * The current credential's signature is valid
  * The new credential's proof of possession is valid
  * The rotation request has not expired
  * Wallet policies permit the credential change

  If all checks pass, the on-chain `rotate_passkey()` transaction is submitted and confirmed.

  ### Rotation completes — new credential is active

  Once the network confirms the transaction, the new passkey is the active credential for the wallet. The old passkey can no longer authorize transactions or sign in.

  ```typescript src/components/RotationSuccessScreen.tsx theme={null}
  export function RotationSuccessScreen() {
    return (
      <div>
        <h2>Passkey updated successfully</h2>
        <p>
          Your wallet is now secured by your new passkey on this device.
          Your wallet address, balances, and history are unchanged.
        </p>
        <p>
          If you still have access to your old device, you can safely
          remove the old passkey from that device's credential manager.
        </p>
      </div>
    );
  }
  ```

  Notify the user via email or push notification as well — an unexpected rotation notification is an early warning of a potential compromise.
</Steps>

## Implementing rotation in your UI

Place credential rotation in a **Security** section of your account settings — not on the home screen. Users who need it will know to look there; casual users won't stumble into it accidentally.

```typescript src/screens/RotateCredentialScreen.tsx theme={null}
import { useState } from "react";
import { startCredentialRotation } from "../services/rotation";

type RotationStatus = "idle" | "in-progress" | "success" | "error";

export function RotateCredentialScreen() {
  const [status, setStatus] = useState<RotationStatus>("idle");
  const [error, setError] = useState<string | null>(null);

  const handleRotate = async () => {
    setStatus("in-progress");
    setError(null);
    try {
      await startCredentialRotation();
      setStatus("success");
    } catch (err: unknown) {
      setError(
        err instanceof Error
          ? err.message
          : "Credential rotation failed. Please try again."
      );
      setStatus("error");
    }
  };

  if (status === "success") {
    return <RotationSuccessScreen />;
  }

  return (
    <div>
      <h2>Update Your Passkey</h2>

      <p>
        Use this if you're moving to a new device or want to upgrade your
        sign-in credential. Your wallet address and assets will not change.
      </p>

      {error && (
        <p role="alert" style={{ color: "red" }}>
          {error}
        </p>
      )}

      <button
        onClick={handleRotate}
        disabled={status === "in-progress"}
      >
        {status === "in-progress" ? "Updating passkey…" : "Update Passkey"}
      </button>

      <p style={{ fontSize: "0.875rem", color: "#6B7280" }}>
        You'll be prompted to create a new passkey on this device.
        Make sure you're on the device you want to use going forward.
      </p>
    </div>
  );
}
```

## Rotation error handling

| Error                          | Likely cause                                                                                 | Recommended response                                                       |
| ------------------------------ | -------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
| Authorization failed           | Current passkey signature invalid — may indicate the credential was deleted between sessions | Ask the user to sign in again; if they can't, redirect to account recovery |
| Credential verification failed | The new passkey could not complete proof of possession                                       | Ask the user to retry the rotation on their new device                     |
| Proof of possession failed     | Challenge signature invalid                                                                  | Retry; may be a transient platform issue                                   |
| Authorization expired          | User took too long between steps                                                             | Restart the rotation flow from the beginning                               |

```typescript src/services/rotation.ts theme={null}
import { socketfi } from "../socketfi/client";

export async function startCredentialRotation() {
  try {
    return await socketfi.rotateCredential();
  } catch (err: unknown) {
    const message = err instanceof Error ? err.message : "";

    if (message.toLowerCase().includes("authorization")) {
      throw new Error(
        "We couldn't verify your current passkey. Please sign in again and retry."
      );
    }

    if (message.toLowerCase().includes("expired")) {
      throw new Error(
        "The rotation request expired. Please start again."
      );
    }

    throw new Error("Credential rotation failed. Please try again.");
  }
}
```

## Monitoring and notifications after rotation

Log every rotation event and notify the user immediately. An unexpected rotation notification — one the user did not initiate — is a strong signal of account compromise.

```typescript src/server/services/rotationAudit.ts theme={null}
type RotationEvent = {
  timestamp: number;
  walletAddress: string;
  outcome: "success" | "failure";
  reason?: string;
  ipAddress?: string;
  userAgent?: string;
};

export async function logRotationEvent(event: RotationEvent) {
  await auditLog.write({ ...event, type: "credential_rotation" });

  if (event.outcome === "success") {
    // Always notify the user — they need to know their credential changed
    await notifications.send({
      walletAddress: event.walletAddress,
      subject: "Your passkey has been updated",
      body: `Your SocketFi wallet passkey was updated on ${new Date(event.timestamp).toLocaleString()}. If you didn't do this, contact support immediately.`,
    });
  }

  if (event.outcome === "failure") {
    await alerting.increment(`rotation.failures.${event.walletAddress}`);
  }
}
```

## Production checklist

* ✅ Surface credential rotation in a **Security** settings section, not on the main dashboard
* ✅ Gate the rotation screen behind an authenticated session — never allow unauthenticated rotation
* ✅ Show clear step-by-step progress so users know which device to complete the steps on
* ✅ Send a notification (email or push) every time rotation completes
* ✅ Log all rotation events with timestamp, wallet address, outcome, and IP
* ✅ Alert on repeated rotation failures for the same wallet
* ✅ Remind users to rotate before disposing of old devices — consider adding a prompt in device/account settings flows
* ✅ Test the full rotation flow on both iOS and Android before launch
