{#each steps as stepName, i}
{i < getCurrentStepIndex() ? '✓' : i + 1}
{stepName}
{#if i < steps.length - 1}
{/if} {/each}
{#if flow.state.error}
{flow.state.error}
{/if} {#if flow.state.step === 'welcome'}

Migrate Your Account Here

This wizard will help you move your AT Protocol account from another PDS to this one.

What will happen:

  1. Log in to your current PDS
  2. Choose your new handle on this server
  3. Your repository and blobs will be transferred
  4. Verify the migration via email
  5. Your identity will be updated to point here
Before you proceed:
  • You need access to the email registered with your current account
  • Large accounts may take several minutes to transfer
  • Your old account will be deactivated after migration
{:else if flow.state.step === 'source-login'}

{isResumedMigration ? 'Resume Migration' : 'Log In to Your Current PDS'}

{isResumedMigration ? 'Enter your credentials to continue the migration.' : 'Enter your credentials for the account you want to migrate.'}

{#if isResumedMigration}

Your migration was interrupted. Log in to both accounts to resume.

Migrating: {flow.state.sourceHandle}{flow.state.targetHandle}

{/if}

Your current handle on your existing PDS

Your account password (not an app password)

{#if flow.state.requires2FA}

Check your email for the verification code

{/if} {#if isResumedMigration}

The password you set for your account on this PDS

{/if}
{:else if flow.state.step === 'choose-handle'}

Choose Your New Handle

Select a handle for your account on this PDS.

Migrating from: {flow.state.sourceHandle}
{#if serverInfo && serverInfo.availableUserDomains.length > 0 && !handleInput.includes('.')} {/if}
{#if checkingHandle}

Checking availability...

{:else if handleAvailable === true}

Handle is available!

{:else if handleAvailable === false}

Handle is already taken

{:else}

You can also use your own domain by entering the full handle (e.g., alice.mydomain.com)

{/if}
flow.updateField('targetEmail', (e.target as HTMLInputElement).value)} required />
flow.updateField('targetPassword', (e.target as HTMLInputElement).value)} required minlength="8" />

At least 8 characters

{#if serverInfo?.inviteCodeRequired}
flow.updateField('inviteCode', (e.target as HTMLInputElement).value)} required />
{/if}
{:else if flow.state.step === 'review'}

Review Migration

Please confirm the details of your migration.

Current Handle: {flow.state.sourceHandle}
New Handle: {flow.state.targetHandle}
DID: {flow.state.sourceDid}
From PDS: {flow.state.sourcePdsUrl}
To PDS: {window.location.origin}
Email: {flow.state.targetEmail}
Final confirmation: After you click "Start Migration", your repository and data will begin transferring. This process cannot be easily undone.
{:else if flow.state.step === 'migrating'}

Migration in Progress

Please wait while your account is being transferred...

{flow.state.progress.repoExported ? '✓' : '○'} Export repository
{flow.state.progress.repoImported ? '✓' : '○'} Import repository
{flow.state.progress.blobsMigrated === flow.state.progress.blobsTotal && flow.state.progress.blobsTotal > 0 ? '✓' : '○'} Migrate blobs ({flow.state.progress.blobsMigrated}/{flow.state.progress.blobsTotal})
{flow.state.progress.prefsMigrated ? '✓' : '○'} Migrate preferences
{#if flow.state.progress.blobsTotal > 0}
{/if}

{flow.state.progress.currentOperation}

{:else if flow.state.step === 'email-verify'}

{$_('migration.inbound.emailVerify.title')}

{@html $_('migration.inbound.emailVerify.desc', { values: { email: `${flow.state.targetEmail}` } })}

{$_('migration.inbound.emailVerify.hint')}

{#if flow.state.error}
{flow.state.error}
{/if}
flow.updateField('emailVerifyToken', (e.target as HTMLInputElement).value)} disabled={loading} required />
{:else if flow.state.step === 'plc-token'}

Verify Migration

A verification code has been sent to the email registered with your old account.

This code confirms you have access to the account and authorizes updating your identity to point to this PDS.

flow.updateField('plcToken', (e.target as HTMLInputElement).value)} disabled={loading} required />
{:else if flow.state.step === 'did-web-update'}

{$_('migration.inbound.didWebUpdate.title')}

{$_('migration.inbound.didWebUpdate.desc')}

{$_('migration.inbound.didWebUpdate.yourDid')} {flow.state.sourceDid}

{$_('migration.inbound.didWebUpdate.updateInstructions')}

{`{
  "@context": [
    "https://www.w3.org/ns/did/v1",
    "https://w3id.org/security/multikey/v1",
    "https://w3id.org/security/suites/secp256k1-2019/v1"
  ],
  "id": "${flow.state.sourceDid}",
  "alsoKnownAs": [
    "at://${flow.state.targetHandle || '...'}"
  ],
  "verificationMethod": [
    {
      "id": "${flow.state.sourceDid}#atproto",
      "type": "Multikey",
      "controller": "${flow.state.sourceDid}",
      "publicKeyMultibase": "${flow.state.targetVerificationMethod?.replace('did:key:', '') || '...'}"
    }
  ],
  "service": [
    {
      "id": "#atproto_pds",
      "type": "AtprotoPersonalDataServer",
      "serviceEndpoint": "${window.location.origin}"
    }
  ]
}`}
{$_('migration.inbound.didWebUpdate.important')} {$_('migration.inbound.didWebUpdate.verifyFirst')} {$_('migration.inbound.didWebUpdate.fileLocation')} https://{flow.state.sourceDid.replace('did:web:', '')}/.well-known/did.json
{:else if flow.state.step === 'finalizing'}

Finalizing Migration

Please wait while we complete the migration...

{flow.state.progress.plcSigned ? '✓' : '○'} Sign identity update
{flow.state.progress.activated ? '✓' : '○'} Activate new account
{flow.state.progress.deactivated ? '✓' : '○'} Deactivate old account

{flow.state.progress.currentOperation}

{:else if flow.state.step === 'success'}

Migration Complete!

Your account has been successfully migrated to this PDS.

Your new handle: {flow.state.targetHandle}
DID: {flow.state.sourceDid}
{#if flow.state.progress.blobsFailed.length > 0}
Note: {flow.state.progress.blobsFailed.length} blobs could not be migrated. These may be images or other media that are no longer available.
{/if}

Redirecting to dashboard...

{:else if flow.state.step === 'error'}

Migration Error

An error occurred during migration.

{flow.state.error}
{/if}