Migrating to 2.0
If your app previously used Privy’s Swift 1.Y.Z
SDK, follow the migration guide below to upgrade to 2.0
. The migration guide is split into logical sections that outline related breaking changes.
Initialization
1. App client ID required at initialization
Previously, apps were only required to pass in an appId
when initializing the Privy SDK. Now, appClientId
is required too. You can retrieve more information on how to retrieve your appClientId here.
2. PrivySdk.initialize can only be called once
It’s important to use a single instance of Privy across the lifetime of your application. Calling PrivySdk.initialize multiple times will result in a fatal error.
3. privy.awaitReady()
When the Privy SDK is first initialized, the user’s authentication state will be set to notReady
until Privy finishes initialization. We’ve added an async privy.awaitReady()
function that allows you to await initialization completion. During this time, we suggest you show a loading state to your user.
Calling PrivySDK functions before calling privy.awaitReady()
might result in unexpected
functionality.
Here’s an example with some pseudocode:
Authentication
AuthState
The AuthState
represents the authentication state of your user.
Accessing AuthState
The current auth state can be accessed any time via privy.authState
.
Subscribing to AuthState updates
Auth state updates are exposed via privy.authStatePublisher
, which utilizes Combine’s AnyPublisher.
The PrivyUser
After authenticating a user via any login method, you will receive the PrivyUser
object. The PrivyUser
represents an authenticated user. All user specific actions, such as creating a wallet or retrieving the user’s access token, are accessed via the PrivyUser
.
You may retrieve the PrivyUser
anytime by calling privy.user
. If this value is non-null, there is an authenticated user. If the value is null, there is no authenticated user.
The PrivyUser
can also be retrieved via the associated type of the “authenticated” auth state:
Use the PrivyUser
object to:
- Get the user’s ID
- Get the user’s identity token
- Get the user’s access token
- Get the user’s linked accounts
- Get the user’s embedded Ethereum wallets
- Get the user’s embedded Solana wallets
- Create an embedded Ethereum wallet
- Create an embedded Solana wallet
- Refresh the user
- Log the user out
Miscellaneous
Errors
We’ve significantly enhanced our error handling. When an SDK function throws an error, it will be a PrivyError
, which contains an errorCode
and a localizedDescription
.
AuthSession
The AuthSession
is no longer exposed. Values previously available in AuthSession are now available through different methods:
PrivyUser
: can be accessed viaprivy.user
as described above.accessToken
: can be accessed viaprivy.user.getAccessToken()
. This method will return the user’s access token, refreshing the session if needed.
Session Refresh
To refresh / update a PrivyUser
, you’d previously call privy.refreshSession
. Now, trigger the refresh via the PrivyUser
, specifically, privyUser.refresh
.
Logout
To logout an authenticate user, call privyUser.logout()
instead of privy.logout()
. Once calling logout, the PrivyUser
instance is no longer valid.
Linked Accounts
LinkedAccount
and its associated types are no longerCodable
,Hashable
,Identifiable
orEquatable
.LinkedAccount.embeddedWallet
is now split into chain specific values -LinkedAccount.embeddedEthereumWallet
andLinkedAccount.embeddedSolanaWallet
- The
chainId
property on the embedded wallet linked accounts is removed.
Other type changes
firstVerifiedAt
,latestVerifiedAt
, andcreatedAt
fields now have typeDate
instead ofTimeInterval
orInt
verifiedAt
fields now replaced withfirstVerifiedAt
andlatestVerifiedAt
LoginMethod
is no longerEquatable
Login with SMS
- The
OtpFlowState
enum is no longer exposed. You should manually handle state management based on function results. For example, ifLoginWithSms.loginWithCode
throws an error, you can catch the error and update your UI accordingly. LoginWithSms.sendCode
now throws an error if sending code is unsuccessful, instead of returning falseLoginWithSms.loginWithCode
now returnsPrivyUser
LoginWithSms.loginWithCode
now requires phone number to be passed in as a parameter (previously was optional)
Login with email
- The
OtpFlowState
enum is no longer exposed. You should manually handle state management based on function results. For example, ifLoginWithEmail.loginWithCode
throws an error, you can catch the error and update your UI accordingly. LoginWithEmail.sendCode
now throws an error if sending code is unsuccessful, instead of returning falseLoginWithEmail.linkWithCode
no longer returns anything, and throws an error if linking failsLoginWithEmail.loginWithCode
now returnsPrivyUser
LoginWithEmail.loginWithCode
now requires email to be passed in (no longer optional)
Login with custom auth
LoginWithCustomAccessToken.loginWithCustomAccessToken
now returnsPrivyUser
- When initializing the PrivySDK, you should now pass the
TokenProvider
through thePrivyLoginWithCustomAuthConfig
field in thePrivyConfig
object. This allows Privy to access your user’s access token at initialization while attempting to restore the Privy user’s session.
Login with SIWE
SiweFlowState
enum is no longer exposed. You should manually handle state management based on function results. For example, ifLoginWithSiwe.loginWithSiwe
throws an error, you can catch the error and update your UI accordingly.LoginWithSiwe.loginWithSiwe
now returnsPrivyUser
LoginWithSiwe.loginWithSiwe
now requires message and params to be passed in (no longer optional)LoginWithSiwe.linkWithSiwe
no long returns anything, and throws an error if linking failsLoginWithSiwe.linkWithSiwe
now requires message and params to be passed in (no longer optional)
Login with OAuth
- LoginWithOAuth.login now returns
PrivyUser
Embedded wallets
Overview
Previously, all embedded wallet APIs were accessible directly from the privy.embeddedWallet
object, which is no longer available.
All embedded wallet APIs are now available via the PrivyUser
instead. This is because all embedded wallet actions require an authenticated user, so adding the methods inside the authenticated PrivyUser
was the most logical.
As an example, when creating an Ethereum wallet:
Connecting the wallet
In SDK 1.Y.Z, you had to ensure wallets were connected prior to accessing them by calling privy.connectWallet()
. This method is now removed as we handle connected state internally! You may access the user’s embedded wallets at anytime, without ensuring “wallet connected” state.
Because you no longer need to manage wallet state, EmbeddedWalletState
has been removed.
Ethereum vs Solana
Now, all embedded wallet APIs are chain specific and available via the PrivyUser
.
Creating a wallet
Ethereum:
Solana:
Retrieving a wallet
Ethereum:
Solana:
Using a wallet / rpc providers
Instead of grabbing the wallet’s provider via try privy.embeddedWallet.getEthereumProvider(for: wallet.address)
, the provider is now available directly on the wallet instance. For example:
Ethereum:
Solana:
Changing the EVM chain
When utilizing the EmbeddedEthereumWalletProvider
, you may specify the EVM Chain by calling provider.switchChain
. This was previously named provider.configure
.
Was this page helpful?