Appearance
Using a wallet from another app
Once a user has authorized access to their account on other apps, via the cross-app ecosystem, you can use the wallets of that account to do things like sign messages and send transactions.
Getting linked provider wallets
Once a user has successfully linked their account from a provider app, an account of type: 'cross_app'
will be added to the linked_accounts
array of their user
object. You can find this account like so:
tsx
const {user} = usePrivy();
const crossAppAccount = user.linked_accounts.find((account) => account.type === 'cross_app');
This crossAppAccount
is an object with the following properties:
Field | Type | Value |
---|---|---|
type | 'cross_app' | Indicates that the linked account is a cross-app account. |
embedded_wallets | {address: string}[] | An array of the user's embedded wallet(s) from the provider app for the cross-app account. |
smart_wallets | {address: string}[] | An array of the user's smart wallet(s) from the provider app for the cross-app account. |
providerApp | ProviderAppMetadata | Metadata about the provider app for the cross-app account. |
firstVerifiedAt | Date | Datetime when the cross-app account was first linked to the user. |
latestVerifiedAt | Date | Datetime for when the user last logged in/linked the cross-app account. |
To get the user's embedded wallet address from this account, simply inspect the embedded_wallets
field of the crossAppAccount
:
tsx
const embeddedWalletAddress = crossAppAccount.embedded_wallets[0].address;
TIP
Cross-app operations on Smart Wallets work exactly the same! Just use the right wallet address and all hooks will work as usual.
tsx
const smartWalletAddress = crossAppAccount.smart_wallets[0].address;
To get metadata about the provider app for the wallet, such as its Privy app ID, name, and logo, inspect the providerApp
field of crossAppAccount
:
tsx
const providerApp = crossAppAccount.providerApp;
This providerApp
metadata is an object with the following properties:
Field | Type | Value |
---|---|---|
id | string | Privy app ID of the source app. |
name | string? | Name of the source app. |
logoUrl | string? | Logo of the source app. |
Using wallets from a provider
Once a user has successfully linked a cross-app account, the user may use their embedded wallet from the provider app within your app per the interfaces below.
Getting the wallet address
To find a user's cross-app embedded wallet, first find the account of type: 'cross_app'
from their linked_accounts
array. If your app permits users to link cross-app accounts from multiple provider apps, you should also filter the linked_accounts
by the provider_app_id
on the cross-app account.
tsx
// Replace `providerAppId` with the Privy app ID of your desired provider app
const providerAppId = 'insert-provider-app-id';
const crossAppAccount = user.linked_accounts.find(
(account) => account.type === 'cross_app' && account.provider_app_id === providerAppId,
);
Next, from the crossAppAccount
, inspect the embedded_wallets
array to get the user's embedded wallet address(es) from the source app.
tsx
const address = crossAppAccount.embedded_wallets[0].address;
INFO
Most users only have one embedded wallet per app. Certain apps, however, leverage multiple embedded wallets (e.g. HD wallets) per user to support certain use cases. In kind, the embedded_wallets
field is designed as an array, but generally will be a singleton containing one entry.
Requesting signatures and transaction
INFO
When you request a signature or transaction from a user's embedded wallet from another app, Privy requires the user to explicitly confirm the signature or transaction. This is accomplished by opening a popup to the provider app's domain, where the user confirms the action in an isolated environment.
To request signatures and transactions from a user's embedded wallet from a provider app, use the signMessage
, signTypedData
, and sendTransaction
methods returned by Privy's hooks: useSignMessageWithCrossApp
, useSignTypedDataWithCrossApp
and useSendTransactionWithCrossApp
:
These methods all require an additional address
property, and an optional redirectUri
, of the following types:
Parameter | Type | Description |
---|---|---|
address | string | The address for the cross-app embedded wallet that you'd like to request a signature/transaction from. |
redirectUri | string | (Optional) A URL path that the provider will automatically redirect to after successful authentication. This defaults to a link back to your app root, eg. '/' , if not provided. |
If the address
you specify in this CrossAppWalletOptions
object is not a valid embedded wallet that has been linked to the current user from a provider app, these wallet methods will error.
Continue below for the specific parameters required by each method.
signMessage
To the signMessage
method returned by `useSignMessageWithCrossApp``, pass the following parameters:
Parameter | Type | Description |
---|---|---|
message | string | The message the user must sign as a string . |
address | string | The address for the cross-app embedded wallet that you'd like to request a signature/transaction from. |
redirectUri | string | (Optional) A URL path that the provider will automatically redirect to after successful authentication. This defaults to a link back to your app root, eg. '/' , if not provided. |
signTypedData
To the signTypedData
method returned by `useSignTypedDataWithCrossApp``, pass the following parameters:
Parameter | Type | Description |
---|---|---|
typedData | TypedDataDefinition | A JSON object that conforms to the EIP-712 TypedData JSON schema. |
address | string | The address for the cross-app embedded wallet that you'd like to request a signature/transaction from. |
redirectUri | string (optional) | A URL path that the provider will automatically redirect to after successful authentication. This defaults to a link back to your app root, eg. '/' , if not provided. |
sendTransaction
To the sendTransaction
method returned by `useSendTransactionWithCrossApp``, pass the following parameters:
Parameter | Type | Description |
---|---|---|
requestData | UnsignedTransactionRequest | The transaction request to be sent. |
address | string | The address for the cross-app embedded wallet that you'd like to request a signature/transaction from. |
redirectUri | string (optional) | A URL path that the provider will automatically redirect to after successful authentication. This defaults to a link back to your app root, eg. '/' , if not provided. |
Example signature request
As an example, you might request a signature from a user's cross-app wallet like so:
tsx
import {usePrivy, useSignMessageWithCrossApp} from '@privy-io/expo';
function Button() {
const {user} = usePrivy();
const {signMessage} = useSignMessageWithCrossApp();
const crossAppAccount = user.linked_accounts.find((account) => account.type === 'cross_app');
const address = crossAppAccount.embedded_wallets[0].address;
return (
<button onClick={() => signMessage('Hello world', {address: address})} disabled={!address}>
Sign a message with your cross-app wallet
</button>
);
}