Hierarchical deterministic (HD) wallets
Privy embedded wallets are hierarchical deterministic (HD) wallets. An HD wallet allows you to generate multiple addresses and private keys from a shared source of entropy: the wallet seed (or equivalently, a BIP-39 mnemonic encoding the seed, known as a seed phrase).
In kind, Privy can be used to provision multiple embedded wallets for a single user. Read more below to learn how!
Creating multiple HD wallets
To create multiple HD wallets for a user, use the createWallet
method:
Creating the user’s first wallet
If this is the first wallet you are creating for the user (e.g. the 0th index), you may call createWallet
with no parameters:
Creating additional wallets
There are two approaches to creating additional wallets.
1. Create an additional wallet with the next available index
If the user already has an embedded wallet, and you are creating an additional embedded wallet, call createWallet
with createAdditional
set to true
:
If true
, will allow the user to create a wallet regardless if it is their first wallet or an
additional wallet. If false
, createWallet will succeed only if the use is creating their first
wallet. Defaults to false
.
Once invoked, createWallet
will return a Promise that resolves to the Wallet
created for the user at the specified index, if it was successful. This method will reject with an error if:
- the user is not
authenticated
- the user already has an embedded wallet and
createAdditional
was not set totrue
- if there is another error during wallet creation, such as the user exiting prematurely
2. Create an additional wallet with a specified HD wallet index
To create a wallet at a specified HD wallet index, call createWallet
with the preferred walletIndex
.
This method will either create a new wallet, or return the existing one if one already exists at the specified index.
The specified HD wallet index. Must be a positive number, and must be 0
for the user’s first
wallet.
A wallet with HD index 0 must be created before creating a wallet at greater HD indices.
An error can be thrown if:
- the user is not
authenticated
- wallet creation fails or the wallet cannot be added to the user’s account.
- an invalid HD wallet index is supplied, i.e.
walletIndex
is less than 0, or ifwalletIndex
is greater than 0 while user has no wallet with HD index 0.
Since HD wallets use the same underlying wallet seed, the recovery method for the wallet is shared across all of a user’s embedded wallets.
Using multiple HD wallets
Getting a specific embedded wallet
Once a user has one or more embedded wallets, the wallets are added to both linkedAccounts
array of the user
object and the array of connected wallets returned by useWallets
.
To find a specific embedded wallet for the user, search the useWallets
array for a wallet with walletClientType: 'privy'
and an address
that matches your desired address:
You can also get a list of all of the user’s embedded wallets by filtering the useWallets
array for entries with walletClientType: 'privy'
:
Requesting signatures and transactions
Your app can then use Privy’s native signature and transaction methods, the wallet’s EIP1193 provider, or a third-party library like viem
or ethers
, per the instructions below.
Using Privy’s native signature and transaction methods
To use Privy’s native signMessage
, signTypedData
, and sendTransaction
methods with a specific embedded wallet, simply pass the address for your desired wallet as the final optional parameter to these methods:
Using the EIP1193 provider, viem, and ethers (EVM only)
You can also request signatures and transactions from a specific embedded wallet using the wallet’s EIP1193 provider or a library like viem
or ethers
.
To get the EIP1193 provider for a specific embedded wallet, first find the corresponding ConnectedWallet
object from the useWallets
array:
Then, call the object’s getEthereumProvider
method to get an EIP1193 provider for that wallet:
You can then easily pass that EIP1193 provider to a library like viem
or ethers
to use those libraries’ interfaces to send requests to the wallet.
Exporting HD wallets
To export the private key or seed phrase for a specific HD wallet, simply pass the address of the wallet you’d like to export as an address
parameter to the exportWallet
method:
If no address
is passed to exportWallet
, Privy will default to exporting the non-imported wallet at walletIndex: 0
.
Pregenerating multiple HD wallets (EVM only)
Privy supports pregenerating multiple HD wallets in Ethereum when creating new users. With our user import endpoint, you can create a user with up to 10 pregenerated HD wallets. Simply call the import endpoint with create_n_ethereum_wallets
set to the number of embedded wallets you want to generate for your user.
Pregeneration endpoints have heavier rate limit of 240 users per minute. If you are being rate limited, responses will have status code 429. We suggest you setup exponential back-offs starting at 1 second to seamlessly recover.
Below is a sample cURL command for pregenerating two new wallets for a user with Privy:
A successful response will include the new user object along with their Privy user ID and embedded wallet addresses, like below. The generated wallets will be available to the user upon sign in.
Below is a sample successful response for generating two new wallets for a user with Privy:
Creating multiple HD wallets
To create multiple HD wallets for a user, use the createWallet
method:
Creating the user’s first wallet
If this is the first wallet you are creating for the user (e.g. the 0th index), you may call createWallet
with no parameters:
Creating additional wallets
There are two approaches to creating additional wallets.
1. Create an additional wallet with the next available index
If the user already has an embedded wallet, and you are creating an additional embedded wallet, call createWallet
with createAdditional
set to true
:
If true
, will allow the user to create a wallet regardless if it is their first wallet or an
additional wallet. If false
, createWallet will succeed only if the use is creating their first
wallet. Defaults to false
.
Once invoked, createWallet
will return a Promise that resolves to the Wallet
created for the user at the specified index, if it was successful. This method will reject with an error if:
- the user is not
authenticated
- the user already has an embedded wallet and
createAdditional
was not set totrue
- if there is another error during wallet creation, such as the user exiting prematurely
2. Create an additional wallet with a specified HD wallet index
To create a wallet at a specified HD wallet index, call createWallet
with the preferred walletIndex
.
This method will either create a new wallet, or return the existing one if one already exists at the specified index.
The specified HD wallet index. Must be a positive number, and must be 0
for the user’s first
wallet.
A wallet with HD index 0 must be created before creating a wallet at greater HD indices.
An error can be thrown if:
- the user is not
authenticated
- wallet creation fails or the wallet cannot be added to the user’s account.
- an invalid HD wallet index is supplied, i.e.
walletIndex
is less than 0, or ifwalletIndex
is greater than 0 while user has no wallet with HD index 0.
Since HD wallets use the same underlying wallet seed, the recovery method for the wallet is shared across all of a user’s embedded wallets.
Using multiple HD wallets
Getting a specific embedded wallet
Once a user has one or more embedded wallets, the wallets are added to both linkedAccounts
array of the user
object and the array of connected wallets returned by useWallets
.
To find a specific embedded wallet for the user, search the useWallets
array for a wallet with walletClientType: 'privy'
and an address
that matches your desired address:
You can also get a list of all of the user’s embedded wallets by filtering the useWallets
array for entries with walletClientType: 'privy'
:
Requesting signatures and transactions
Your app can then use Privy’s native signature and transaction methods, the wallet’s EIP1193 provider, or a third-party library like viem
or ethers
, per the instructions below.
Using Privy’s native signature and transaction methods
To use Privy’s native signMessage
, signTypedData
, and sendTransaction
methods with a specific embedded wallet, simply pass the address for your desired wallet as the final optional parameter to these methods:
Using the EIP1193 provider, viem, and ethers (EVM only)
You can also request signatures and transactions from a specific embedded wallet using the wallet’s EIP1193 provider or a library like viem
or ethers
.
To get the EIP1193 provider for a specific embedded wallet, first find the corresponding ConnectedWallet
object from the useWallets
array:
Then, call the object’s getEthereumProvider
method to get an EIP1193 provider for that wallet:
You can then easily pass that EIP1193 provider to a library like viem
or ethers
to use those libraries’ interfaces to send requests to the wallet.
Exporting HD wallets
To export the private key or seed phrase for a specific HD wallet, simply pass the address of the wallet you’d like to export as an address
parameter to the exportWallet
method:
If no address
is passed to exportWallet
, Privy will default to exporting the non-imported wallet at walletIndex: 0
.
Pregenerating multiple HD wallets (EVM only)
Privy supports pregenerating multiple HD wallets in Ethereum when creating new users. With our user import endpoint, you can create a user with up to 10 pregenerated HD wallets. Simply call the import endpoint with create_n_ethereum_wallets
set to the number of embedded wallets you want to generate for your user.
Pregeneration endpoints have heavier rate limit of 240 users per minute. If you are being rate limited, responses will have status code 429. We suggest you setup exponential back-offs starting at 1 second to seamlessly recover.
Below is a sample cURL command for pregenerating two new wallets for a user with Privy:
A successful response will include the new user object along with their Privy user ID and embedded wallet addresses, like below. The generated wallets will be available to the user upon sign in.
Below is a sample successful response for generating two new wallets for a user with Privy:
Creating multiple HD wallets
To create multiple Ethereum wallets for a user, use the create
method from the useEmbeddedEthereumWallet
hook:
As a parameter to create
, pass an object containing a createAdditional
boolean specifying if you would like to create an additional wallet, even if the user has an existing one.
If true
, will allow the user to create a Ethereum wallet regardless if it is their first wallet
or an additional wallet. If false
, createWallet will succeed only if the use is creating their
first wallet. Defaults to false
.
Once invoked, create
will return a Promise that resolves to the newly created wallet, if it was successful. This method will reject with an error if:
- the user is not
authenticated
. - the user already has an embedded Ethereum wallet and
createAdditional
was not set totrue
. - if there is another error during wallet creation, such as the user exiting prematurely.
Using multiple HD wallets
Once a user has one or more embedded wallets, the wallets are added to the wallets
array returned by useEmbeddedEthereumWallet
:
Refer to the requests section to learn how to interact with the wallets you create.
Getting a specific embedded wallet
To find a specific embedded wallet for the user, search the wallets
array for a wallet with the address
that matches your desired address:
You can alternatively search the wallets array by your desired HD index:
Creating multiple HD wallets
To create multiple Ethereum wallets for a user, use the create
method from the useEmbeddedEthereumWallet
hook:
As a parameter to create
, pass an object containing a createAdditional
boolean specifying if you would like to create an additional wallet, even if the user has an existing one.
If true
, will allow the user to create a Ethereum wallet regardless if it is their first wallet
or an additional wallet. If false
, createWallet will succeed only if the use is creating their
first wallet. Defaults to false
.
Once invoked, create
will return a Promise that resolves to the newly created wallet, if it was successful. This method will reject with an error if:
- the user is not
authenticated
. - the user already has an embedded Ethereum wallet and
createAdditional
was not set totrue
. - if there is another error during wallet creation, such as the user exiting prematurely.
Using multiple HD wallets
Once a user has one or more embedded wallets, the wallets are added to the wallets
array returned by useEmbeddedEthereumWallet
:
Refer to the requests section to learn how to interact with the wallets you create.
Getting a specific embedded wallet
To find a specific embedded wallet for the user, search the wallets
array for a wallet with the address
that matches your desired address:
You can alternatively search the wallets array by your desired HD index:
Creating multiple HD wallets
To create multiple Solana wallets for a user, use the create
method from the useEmbeddedSolanaWallet
hook:
As an optional parameter to create
, you may pass an object containing the following fields:
If true
, will allow the user to create a Solana wallet regardless if it is their first wallet or
an additional wallet. If false
, createWallet will succeed only if the use is creating their
first wallet. Defaults to false
.
Once invoked, create
will return a Promise that resolves to the provider for the wallet created for the user, if it was successful. This method will reject with an error if:
- the user is not
authenticated
- the user already has an embedded Solana wallet and
createAdditional
was not set totrue
- if there is another error during wallet creation, such as the user exiting prematurely
Creating the user’s first wallet
If this is the first wallet you are creating for the user (e.g. the 0th index), you may call create
with no parameters:
Creating additional wallets
If the user already has an embedded wallet, and you are creating an additional embedded wallet, you must call create
with createAdditional
set to true
:
Using multiple HD wallets
Once a user has one or more embedded wallets, the wallets are added to the wallets
array returned by useEmbeddedSolanaWallet
:
Each entry in the wallets
array is an object with the following fields:
The address (base58-encoded public key) for the wallet.
The address (base58-encoded public key) for the wallet.
The HD index for the wallet.
Method to get a provider for the wallet for requesting signatures and transactions.
Getting a specific embedded wallet
To find a specific embedded wallet for the user, search the wallets
array for a wallet with the address
that matches your desired address:
You can alternatively search the wallets array by your desired HD index:
Requesting signatures and transactions
To request a signature or transaction from a specific embedded wallet, first find the corresponding wallet object from the wallets
array:
Then, call the object’s getProvider
method to get a provider for the wallet:
You can then easily request signatures from the provider
using its request
method, like so:
Creating multiple HD wallets
To create multiple Bitcoin wallets for a user, use the create
method from the useEmbeddedBitcoinWallet
hook:
As a parameter to create
, pass an object containing a chainType
field specifying the type of wallet to create and a createAdditional
boolean specifying if you would like to create an additional wallet of that chainType
, even if the user has an existing wallet of that chainType
.
The type of Bitcoin wallet to create.
If true
, will allow the user to create a Bitcoin wallet regardless if it is their first Bitcoin
wallet or an additional Bitcoin wallet. If false
, createWallet will succeed only if the user is
creating their first wallet. Defaults to false
.
Once invoked, create
will return a Promise that resolves to the newly created wallet, if it was successful. This method will reject with an error if:
- the user is not
authenticated
- the user already has an embedded Bitcoin wallet of the provided
chainType
andcreateAdditional
was not set totrue
- if there is another error during wallet creation, such as the user exiting prematurely
Creating additional wallets
If the user already has an embedded wallet, and you are creating an additional embedded wallet, you must call create
with createAdditional
set to true
:
Using multiple HD wallets
Once a user has one or more embedded wallets, the wallets are added to the wallets
array returned by useEmbeddedBitcoinWallet
:
Refer to the usage section to learn how to interact with the wallets you create.
Getting a specific embedded wallet
To find a specific embedded wallet for the user, search the wallets
array for a wallet with the address
that matches your desired address:
You can alternatively search the wallets array by your desired HD index: