Use this guide for assistance migrating from Para version 1.x to Para’s version 2.0 alpha release. Para 2.0 is in active development, and feature changes are expected while we work toward the final stable version. Developers wanting the latest changes should use the alpha version.

React SDK

Summary of breaking changes

  1. The setup-para CLI tool needs to run before running your app to ensure all @getpara libraries are properly polyfilled. It is recommended to do this in your postinstall step of your package.json, something like:

    "postinstall": "yarn setup-para"
    
  2. The ParaProvider is now required to be used when using the @getpara/react-sdk.@alpha

  3. A queryClient from @tanstack/react-query must be provided.

    See the @tanstack/react-query docs for more information on setting up a QueryClient

  4. The appName prop has moved from a modal prop to a required config prop on the ParaProvider. This name will be used throughout the modal and in any external wallet providers that may be used.

  5. The ParaModal no longer needs to be provided separately, it is automatically included with the ParaProvider and all modal props can be passed to the ParaProvider.

    The ParaModal can still be provided separately if that is preferred. In this case the disableEmbeddedModal: true value should be passed to the ParaProvider config.

  6. The ParaModal props, isOpen and onClose, are no longer required (though they can be provided if desired). These values are now handled by the ParaProvider and developers can use the useModal hook to control the modal state.

  7. When using external wallets the Para connector libraries no longer need to be provided, just installed. All config values for these connectors can be passed to the ParaProvider.

Migration

Migration to V2 can be done one of two ways:

  1. (PREFERRED) Remove the ParaModal component you are providing and use the modal that the updated ParaProvider provides. This option offers the most code reduction and overall simpler developer experience.
  2. Continue to use the ParaModal component you are providing in your app. This option is a bit quicker than the first but will lead to a poorer developer experience.

Remove your <ParaModal> and use the one built into <ParaProvider>. Starting Code:

<QueryClientProvider client={YOUR_QUERY_CLIENT}>
  <ParaProvider
    paraClientConfig={{
      apiKey: "YOUR_API_KEY",
      env: Environment.BETA,
    }}
  >
    {...REST_OF_YOUR_APP}
    <ParaModal
      {...YOUR_MODAL_PROPS}
    />
  </ParaProvider>
</QueryClientProvider>

After Migration:

After Migration
<QueryClientProvider client={YOUR_QUERY_CLIENT}>
  <ParaProvider
    paraClientConfig={{
      apiKey: "YOUR_API_KEY",
      env: Environment.BETA,
    }}
    config={{
      appName: 'Your App Name',
    }}
    paraModalConfig={YOUR_MODAL_PROPS_WITHOUT_APP_NAME}
    externalWalletConfig={{ wallets: [] }}
  >
    {...REST_OF_YOUR_APP}
    {/* Note: <ParaModal /> is removed from here */}
  </ParaProvider>
</QueryClientProvider>

Adding External Wallets

If you’re using external wallets with Para currently, those configs can now be passed to the ParaProvider and the connectors will be instantiated for you. Assuming you already followed the migration steps above, a successful migration would look like:

<ParaCosmosProvider
  selectedChainId={SELECTED_CHAIN_STATE}
  chains={YOUR_COSMOS_CHAINS}
  wallets={[keplrWallet]}
  onSwitchChain={chainId => {
    SELECTED_CHAIN_STATE_UPDATER_FN();
  }}
  multiChain
  walletConnect={{ options: { projectId: 'YOUR_WALLETCONNECT_PROJECT_ID' } }}
>
  <ParaEvmProvider
    config={{
      projectId: 'YOUR_WALLETCONNECT_PROJECT_ID',
      appName: 'Your App Name',
      chains: YOUR_WAGMI_CHAINS,
      wallets: [metaMaskWallet],
    }}
  >
    <ParaSolanaProvider
      endpoint={YOUR_SOLANA_ENDPOINT}
      wallets={[backpackWallet]}
      chain={YOUR_SOLANA_NETWORK}
      // Refer to [https://docs.solanamobile.com/reference/typescript/mobile-wallet-adapter#web3mobilewalletauthorize](https://docs.solanamobile.com/reference/typescript/mobile-wallet-adapter#web3mobilewalletauthorize) for how appIdentity fields work
      appIdentity={{ name: 'Your App Name', uri: 'YOUR_APP_URL' }}
    >
      {...REST_OF_YOUR_APP}
    </ParaSolanaProvider>
  </ParaEvmProvider>
</ParaCosmosProvider>

Notes on the external wallet migration:

  1. All wallets are provided by default, if you wish for them all to be provided you can remove the wallets value in the externalWalletConfig
  2. If you only wish to use EVM wallets only the evmConnector config needs to be passed, the other connectors will be skipped in that case.

Pregen Wallet Methods

Methods dealing with pregen wallets now use a simpler object-based notation to specify the type and identifier the wallet belongs to.

// 1.x
await para.createPregenWallet({
  pregenIdentifier: 'email@email.com',
  pregenIdentifierType: 'EMAIL'
});

// 2.x
await para.createPregenWallet({ pregenId: { email: 'email@email.com' } });

Common Enums (optional)

Enum types used in certain methods, while still available, are now replaced with string union types. You will not be required to import these enums for methods that accept them.

import { WalletType } from '@getpara/web-sdk@alpha';

// Either is allowed
para.createWallet({ type: WalletType.EVM });

para.createWallet({ type: 'EVM' });

Type Definitions

WalletType
string
WalletScheme
string
OAuthMethod
string

Auth Objects

User identity attestations are now represented as auth objects with a single key and value, representing both the type of attestation and the relevant identifier. These objects are used for methods that require an attestation of this type, primarily those for authentication and pre-generated wallet management.

Auth Object Examples

const auth = { email: 'email@test.com' };

await para.signUpOrLogIn({ auth });

Phone number auth objects expect a string in international format, beginning with a + and containing only numbers without spaces or extra characters, i.e.: +${number}. If your UI deals in separated country codes and national phone numbers, you may use the exported formatPhoneNumber function to combine them into a correctly formatted string.

import { formatPhoneNumber } from '@getpara/web-sdk@alpha';

await para.signUpOrLogIn({ auth: { phone: '+13105551234' } });

// or, if your country code and national number are distinct:
await para.signUpOrLogIn({ auth: { phone: formatPhoneNumber('3105551234', '1') } });

Cancelable Methods (optional)

This feature is available in the following SDKs:

  • @getpara/web-sdk@alpha
  • @getpara/react-sdk@alpha
  • @getpara/react-native-sdk@alpha

For methods that wait for user action, such as waitForLogin, you may now pass a callback that is invoked on each polling interval, as well as a callback to indicate whether the method should be canceled and another invoked upon cancelation.

let i = 0, popupWindow: Window;

await para.waitForLogin({
  isCanceled: () => popupWindow?.closed,
  onPoll: () => {
    console.log(`Waiting for login, polled ${++i} times...`)
  },
  onCancel: () => {
    console.log('Login canceled after popup window closed!');
  }
});

New Authentication Flow

The primary methods for authenticating via phone, email address, or third-party services have been overhauled and greatly simplified. If you are using a custom authentication UI, refer to the Custom Authentication UI page for detailed instructions and code samples. For new developers, the Para Modal is the preferred option to handle user authentication in your app.

Modified Core Methods

We’ve streamlined and improved several core methods in version 2.0.0. The following sections outline what’s changed and what actions you need to take.

These changes are required when upgrading to version 2.0.0. Make sure to update your code accordingly to avoid breaking your application.