Appearance
Signing messages ​
Privy allows your app to easily request signatures from users embedded wallet. By default, Privy will display a UI preview of the message to get approval from the user.
These UIs are highly-customizable via params, allowing you to contextualize onchain actions within the broader experience of your product. You can also fully disable Privy's UIs in favor of your own. Learn more about customizing wallet UIs here.
Sign message ​
To request a signature from a user use the signMessage
method returned by the usePrivy
hook:
tsx
const {signMessage} = usePrivy();
When invoked, signMessage
will request an EIP-191 personal_sign
signature from the embedded wallet, and returns a Promise for the user's signature as a string.
signMessage
takes the following parameters. In particular, you can use the optional uiConfig
to customize the prompt shown to the user to contextualize their signing action.
Parameter | Type | Description |
---|---|---|
message | string | Required. The message the user must sign as a string . |
uiConfig | SignMessageModalUIOptions | Optional. Options to customize the signature prompt shown to the user. Defaults to the values outlined below |
uiConfig.showWalletUIs | boolean | Optional. Whether to overwrite the configured wallet UI for the signature prompt. Defaults to undefined , which will respect the server-side or SDK configured option. |
uiConfig.title | string | Optional. The title text for the signature prompt. Defaults to 'Sign'. |
uiConfig.description | string | Optional. The description text for the signature prompt. Defaults to 'Sign to continue'. |
uiConfig.buttonText | string | Optional. The description text for the signature prompt. Defaults to 'Sign and Continue'. |
Example ​
Below is an example of customizing the signature prompt:
tsx
import {usePrivy} from '@privy-io/react-auth';
function SignMessageButton() {
const {signMessage} = usePrivy();
const message = 'Hello world';
const uiConfig = {
title: 'Sample title text',
description: 'Sample description text',
buttonText: 'Sample button text',
};
return (
<button
onClick={async () => {
// Use `signature` below however you'd like
const signature = await signMessage(message, uiConfig);
}}
>
Sign
</button>
);
}
Sign typed data ​
To have a user sign an EIP-712 typed data signature with a custom UI prompt, use the signTypedData
method returned by the usePrivy
hook:
tsx
const {signTypedData} = usePrivy();
When invoked, signTypedData
will request an EIP-721 eth_signTypedData_v4
signature from the embedded wallet, and returns a Promise for the user's signature as a string.
signTypedData
takes the following parameters. In particular, you can use the optional uiConfig
to customize the prompt shown to the user to contextualize their signing action.
Parameter | Type | Description |
---|---|---|
typedData | SignedTypedDataParams | Required. A JSON object that conforms to the EIP-712 TypedData JSON schema. |
uiConfig | SignMessageModalUIOptions | Optional. Options to customize the signature prompt shown to the user. Defaults to the values outlined below |
uiConfig.showWalletUIs | boolean | Optional. Whether to overwrite the configured wallet UI for the signature prompt. Defaults to undefined , which will respect the server-side or SDK configured option. |
uiConfig.title | string | Optional. The title text for the signature prompt. Defaults to 'Sign'. |
uiConfig.description | string | Optional. The description text for the signature prompt. Defaults to 'Sign to continue'. |
uiConfig.buttonText | string | Optional. The description text for the signature prompt. Defaults to 'Sign and Continue'. |
Example ​
Below is an example of customizing the typedData prompt:
tsx
import {usePrivy} from '@privy-io/react-auth';
function SignTypedDataButton() {
const {signTypedData} = usePrivy();
// Example from https://github.com/MetaMask/test-dapp/blob/285ef74eec90dbbb4994eff4ece8c81ba4fc77f9/src/index.js#L1585
const domain = {
name: 'Example Message',
version: '1.0.0',
chainId: 1,
salt: '0',
verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC' as `0x${string}`,
};
// The named list of all type definitions
const types = {
Person: [
{name: 'name', type: 'string'},
{name: 'wallet', type: 'address'},
],
Mail: [
{name: 'from', type: 'Person'},
{name: 'to', type: 'Person'},
{name: 'contents', type: 'string'},
],
// Necessary to define salt param type
EIP712Domain: [
{
name: 'name',
type: 'string',
},
{
name: 'version',
type: 'string',
},
{
name: 'chainId',
type: 'uint256',
},
{
name: 'salt',
type: 'string',
},
{
name: 'verifyingContract',
type: 'string',
},
],
};
// The data to sign
const value = {
from: {
name: 'Cow',
wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826',
},
to: {
name: 'Bob',
wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB',
},
contents: 'Hello, Bob!',
};
const typedData = {primaryType: 'Mail', domain: domain, types: types, message: value};
const uiConfig = {
title: 'Sample title text',
description: 'Sample description text',
buttonText: 'Sample button text',
};
return (
<button
onClick={async () => {
// Use `signature` below however you'd like
const signature = await signTypedData(typedData, uiConfig);
}}
>
Sign Typed Data
</button>
);
}