Skip to main content
A crypto deposit account gives a destination wallet reusable deposit addresses. Each address accepts the assets your app chooses, and Privy converts deposits to one target asset. Privy returns one deposit address for each source chain family in the request, EVM or Solana. Before creating a deposit account, enable app-pays gas sponsorship on each source chain. The destination must be a Privy wallet owned by a single user.
Use createCryptoDepositAccount from the useHeadlessCryptoDeposit hook. The hook signs the request with the authenticated user’s signer.
useHeadlessCryptoDeposit is experimental and requires @privy-io/react-auth 3.46.0 or later. The interface may change without a major SDK version bump.
To use the destination wallet’s own address as the deposit address, set depositAddressStrategy:
To reuse an existing deposit configuration, pass its ID:
ParameterscreateCryptoDepositAccount accepts an object with the following fields:
string
required
ID of the destination wallet. The authenticated user must own this wallet.
'inline_route' | 'deposit_config'
required
inline_route defines the route in the request with source and destination. deposit_config reuses an existing deposit configuration with depositConfigId.
object
Required when type is inline_route. Assets the deposit addresses accept. Chains must be EVM or Solana.
object
Required when type is inline_route. The one asset, on one chain, delivered to the destination wallet.
string
Required when type is deposit_config. ID of an existing deposit configuration.
'dedicated' | 'prefer_destination' | 'require_destination'
Where deposit addresses live. Defaults to dedicated, which always uses separate source wallets. See where deposit addresses live.
ReturnscreateCryptoDepositAccount returns a Promise for an object with a deposit_accounts array. See response.Complete example

Response

Every SDK returns the API response unchanged, with snake_case fields:
object[]
One entry per source route created for the destination wallet.
Show each deposit_address to users as the place to send the listed assets.

Deposit address behavior

Destination requirements. The destination must be a Privy wallet owned by a single user, with no authorization keys or nested key quorums. When a client SDK creates the account, the authenticated user must be that owner. Source wallet reuse. Repeated calls for the same route reuse the same source wallet while it remains eligible. A source wallet stays eligible while it serves only this route and has not been exported. Otherwise, Privy creates a new source wallet. Exported wallets. An exported wallet cannot be a source wallet. Exporting a source wallet for asset recovery stops conversions to it. An exported destination wallet can still receive converted funds from separate source wallets. Destination reuse. With prefer_destination or require_destination, Privy attaches the deposit route to the destination wallet. Other automations attached to the destination wallet are detached. If this route is already attached, Privy keeps it and re-enables it. The default dedicated strategy never changes the destination wallet’s automations.
Changing strategies can change the returned deposit address. Switching to dedicated, including by omitting the option, returns a separate source wallet’s address. Previous routes stay attached, so deposits sent to earlier addresses are still converted. Always show users the latest returned deposit_address.

Error handling

Create rejects on invalid configuration or failed requests. Common error cases include:
  • App-pays gas sponsorship is not enabled on a requested source chain. See setup.
  • The route is unsupported, or the destination chain is not in the destination wallet’s chain family.
  • The destination wallet is not owned by a single user, or the request is not authorized by that user.
  • require_destination is set and the destination wallet was exported.
  • The signed request expires before Privy receives it.
Some apps require the app secret for all wallet actions. For these apps, client SDK requests return a 401. Create the deposit account from a server with NodeJS or the REST API instead. Your app should wrap calls in try/catch and show clear UI feedback.

Next steps

Quote a route

Preview the delivered amount before a deposit

Track orders

Optionally check conversion status after a deposit

Deposit modal

Show a prebuilt deposit UI in React or React Native

Set up crypto deposits

Enable app-pays gas sponsorship on source chains