Linking Accounts from the Para Modal

After your users sign in, they can view their connected wallets (embedded or external) from the Para Modal’s Profile screen. They will also be able to link addtional third-party accounts or browser wallets through the provided user interface. Linking an account simply requires the user to complete the same steps as for a traditional signup. Depending on the account type, they will be prompted to enter a verification code, complete a third-party signup in a popup, or sign a message with their external wallet.

Afterward, you will be able to fetch the linked accounts for the signed-in user via the getLinkedAccounts Para method or the useLinkedAccounts React hook. This call returns their user ID, their primary identifier (the email or phone number they signed up with), and all accounts they have linked thus far.

import { useLinkedAccounts } from "@getpara/react-sdk@alpha";

function App() {
  const { data: linkedAccounts, isLoading, error } = useLinkedAccounts();

  useEffect(() => {
    if (linkedAccounts) {
      // do something with the user's linked accounts
    }
  }, [linkedAccounts])
}

Triggering Account Linking

To trigger the account linking flow programmatically, you can use the useLinkAccount hook. This will open the Para Modal directly to the account linking interface, and allow you to pre-populate the type and identifier if you choose.

Usage
import { useLinkAccount } from "@getpara/react-sdk@alpha";

const { linkAccount, status, error, isPending } = useLinkAccount();

// To open the modal to the list of account options:
linkAccount();

// To open the modal and display a specific set of options:
linkAccount({
  options: ['EMAIL', 'PHONE', 'GOOGLE', 'TWITTER', 'METAMASK', 'PHANTOM']
});

// To open the modal and display all possible external wallet options:
linkAccount({
  options: ['EXTERNAL_WALLET']
});

// To start linking a pre-determined email address or phone number:
linkAccount({
  auth: { email: 'email@example.com' },
});

linkAccount({
  auth: { phone: '+13105551234' },
});

// To link a user-entered email address or phone number:
linkAccount({
  type: 'EMAIL'
});

linkAccount({
  type: 'PHONE'
});

// To link a third-party account, such as Google or Twitter:
linkAccount({
  type: 'GOOGLE'
});

linkAccount({
  type: 'TWITTER'
});

Account Metadata

To fetch account metadata for a particular user from third-party accounts they have linked through your app - for example, their Google profile image or their Discord clan information - use the useGetAccountMetadata React hook or the getAccountMetadata method. This returns an object, indexed by the third-party service name, containing the date of the login and the metadata returned from the service at that time.

import { useGetAccountMetadata } from "@getpara/react-sdk@alpha";

function App() {
  const { data: accountMetadata, isLoading, error } = useGetAccountMetadata();

  useEffect(() => {
    if (accountMetadata) {
      // do something with the user's account metadata
    }
  }, [accountMetadata])
}

Metadata will only be returned for services that the user authenticated with your app specifically. The particular structure of the metadata will depend on the service in question. A sample response might resemble:

{
  "discord": {
    "date": "2022-01-01T00:00:00Z",
    "metadata": {
      "id": "80351110224678912",
      "username": "User",
      "discriminator": "1337",
      "avatar": "8342729096ea3675442027381ff50dfe",
      "verified": true,
      "email": "user@email.com",
      "flags": 64,
      "banner": "06c16474723fe537c283b8efa61a30c8",
      "accent_color": 16711680,
      "premium_type": 1,
      "public_flags": 64,
      "avatar_decoration_data": {
        "sku_id": "1144058844004233369",
        "asset": "a_fed43ab12698df65902ba06727e20c0e"
      }
    }
  },
  "google": {
    "date": "2024-11-01T00:00:00Z",
    "metadata": {
      "id": "000000000000000000000",
      "emails": [
        {
          "value": "test@email.com",
          "verified": true
        }
      ],
      "photos": [
        {
          "value": "https://.../photo.jpg"
        }
      ],
      "provider": "google"
    }
  },
  "x": {
    "date": "2025-01-06T12:34:56Z",
    "metadata": {
      "id": 171290000000000500,
      "url": null,
      "lang": null,
      "name": "Test User",
      "email": "user@email.com",
      "id_str": "171290000000000500",
      "entities": {
        "description": {
          "urls": []
        }
      },
      "location": "",
      "verified": false,
      "following": false,
      "protected": false,
      "suspended": false,
      "time_zone": null,
      "created_at": "Fri Oct 13 19:11:38 +0000 2023",
      "utc_offset": null,
      "description": "",
      "geo_enabled": false,
      "screen_name": "TheirXUsername",
      "listed_count": 0,
      "friends_count": 0,
      "is_translator": false,
      "notifications": false,
      "statuses_count": 0,
      "default_profile": true,
      "followers_count": 0,
      "translator_type": "none",
      "favourites_count": 0,
      "profile_image_url": "http://pbs.twimg.com/profile_images/171290000000000500/hbDmgt_J_normal.png",
      "profile_link_color": "1DA1F2",
      "profile_text_color": "333333",
      "follow_request_sent": false,
      "contributors_enabled": false,
      "has_extended_profile": true,
      "default_profile_image": false,
      "withheld_in_countries": [],
      "is_translation_enabled": false,
      "profile_background_tile": false,
      "profile_image_url_https": "https://pbs.twimg.com/profile_images/171290000000000500/hbDmgt_J_normal.png",
      "needs_phone_verification": false,
      "profile_background_color": "F5F8FA",
      "profile_sidebar_fill_color": "DDEEF6",
      "profile_background_image_url": null,
      "profile_sidebar_border_color": "C0DEED",
      "profile_use_background_image": true,
      "profile_background_image_url_https": null
    }
  }
}