This method uses Ethereum’s
personal_sign RPC method. If you are looking for a low-level raw
signature over a input hash, see
secp256k1_sign.When using Privy’s server-side SDKs to sign messages, you can use the authorization context to
automatically sign requests. Learn more about signing on the
server.
- React
- React Native
- Swift
- Android
- Unity
- Flutter
- NodeJS
- NodeJS (server-auth)
- Java
- Rust
- REST API
Use the
As parameters to
signMessage method exported from the useSignMessage hook to sign a message with an Ethereum embedded wallet.Usage
Report incorrect code
Copy
Ask AI
import {useSignMessage, useWallets} from '@privy-io/react-auth';
const {signMessage} = useSignMessage();
const {wallets} = useWallets();
const uiOptions = {
title: 'You are voting for foobar project'
};
const {signature} = await signMessage(
{message: 'I hereby vote for foobar'},
{
uiOptions,
address: wallets[0].address // Optional: Specify the wallet to use for signing. If not provided, the first wallet will be used.
}
);
Parameters
Message to be signed.
Hide properties
Hide properties
UI options to customize the signature prompt modal. Learn
more
To hide confirmation modals, set
options.uiOptions.showWalletUIs to false. Learn more
about configuring modal prompts here.Address of the wallet to use for signing the message. Recommended when working with external
wallets to ensure reliable functionality. If not provided, the first wallet will be used.
Returns
The signature produced by the wallet.
Callbacks
Configure callbacks for Privy’ssignMessage method on the useSignMessage hook:Report incorrect code
Copy
Ask AI
import {useSignMessage} from '@privy-io/react-auth';
const {signMessage} = useSignMessage({
onSuccess: ({signature}) => {
console.log(signature);
// Any logic you'd like to execute after a user successfully signs a message
},
onError: (error) => {
console.log(error);
// Any logic you'd like to execute after a user exits the message signing flow or there is an error
}
});
// Then call `signMessage` in your code, which will invoke these callbacks on completion
useSignMessage, you may include an onSuccess callback and/or an onError callback.While this component is mounted, any invocation of signMessage will trigger the onSuccess callback or onError callback on completion, depending on if the message was successfully signed or not.onSuccess
If set, theonSuccess callback will execute after a user has successfully signed the message. Within this callback, you can access a signature parameter, which is the signature string value generated by the wallet to sign the message.onError
If set, theonError callback will execute after a user attempts to sign a message and there is an error, or if the user exits the signature flow prematurely. Within this callback, you may access an error code with more information about the error.Request a message signature on the wallets Ethereum provider.
Usage
Report incorrect code
Copy
Ask AI
import {useEmbeddedEthereumWallet} from '@privy-io/expo';
const {wallets} = useEmbeddedEthereumWallet();
const wallet = wallets[0];
// Get an EIP-1193 Provider
const provider = await wallet.getProvider();
// Get address
const accounts = await provider.request({
method: 'eth_requestAccounts'
});
// Sign message
const message = 'I hereby vote for foobar';
const signature = await provider.request({
method: 'personal_sign',
params: [message, accounts[0]]
});
Parameters
The method for the wallet request. For signing messages, this is
'personal_sign'.Returns
The signature produced by the wallet.
Request a message signature on the wallet’s Ethereum provider.
Usage
Report incorrect code
Copy
Ask AI
guard let user = privy.user else {
// If user is null, user is not authenticated
return
}
// Retrieve list of user's embedded Ethereum wallets
let ethereumWallets = user.embeddedEthereumWallets
// Grab the desired wallet. Here, we retrieve the first wallet
guard let wallet = ethereumWallets.first else {
// No ETH wallets
return
}
let signature = try await wallet.provider.request(.personalSign(message: "A message to sign", address: wallet.add))
print("Result signature: \(signature)")
Parameters
The string to sign with the wallet.
The address of the wallet to sign the message with.
Returns
The signature produced by the wallet.
Usage
Report incorrect code
Copy
Ask AI
// Get Privy user
val user = privy.user
// check if user is authenticated
if (user != null) {
// Retrieve list of user's embedded Ethereum wallets
val ethereumWallets = user.embeddedEthereumWallets
if (ethereumWallets.isNotEmpty()) {
// Grab the desired wallet. Here, we retrieve the first wallet
val ethereumWallet = ethereumWallets.first()
// Make an rpc request
ethereumWallet.provider.request(
request = EthereumRpcRequest.personalSign("A message to sign", ethereumWallet.address),
)
}
}
Parameters
The method for the wallet request. For signing messages, this is
'personal_sign'.Returns
The signature produced by the wallet.
Usage
Report incorrect code
Copy
Ask AI
try {
IEmbeddedEthereumWallet embeddedWallet = PrivyManager.Instance.User.EmbeddedWallets[0];
var rpcRequest = new RpcRequest
{m
Method = "personal_sign",
Params = new string[] { "A message to sign", embeddedWallet.Address } // Use the 'new' keyword here
};
RpcResponse personalSignResponse = await embeddedWallet.RpcProvider.Request(rpcRequest);
Debug.Log(personalSignResponse.Data);
} catch (PrivyException.EmbeddedWalletException ex){
Debug.LogError($"Could not sign message due to error: {ex.Error} {ex.Message}");
} catch (Exception ex) {
Debug.LogError($"Could not sign message exception {ex.Message}");
}
Parameters
The method for the wallet request. For signing messages, this is
'personal_sign'.Returns
The signature produced by the wallet.
Usage
Report incorrect code
Copy
Ask AI
// Get an EIP-1193 Provider
final ethereumWallet = privy.user.embeddedEthereumWallets.first;
final provider = ethereumWallet.provider;
// Sign message
final message = 'A message to you Rudy';
final request = EthereumRpcRequest(
method: 'personal_sign',
params: [message, ethereumWallet.address],
);
final result = await provider.request(request);
result.fold(
onSuccess: (response) {
final signature = response.data;
print('Signature: $signature');
},
onFailure: (error) {
print('Error signing message: ${error.message}');
},
);
Parameters
The method for the wallet request. For signing messages, this is
'personal_sign'.Returns
The RPC method executed with the wallet.
Use the
signMessage method on the Ethereum interface to sign a message with an Ethereum wallet.Usage
Report incorrect code
Copy
Ask AI
const {signature, encoding} = await privy.wallets().ethereum().signMessage('insert-wallet-id', {
message: 'Hello world'
});
Parameters and Returns
Check out the API reference for more details.The
@privy-io/server-auth library is deprecated. We recommend integrating @privy-io/node for
the latest features and support.signMessage method on the Ethereum client to sign a message with an Ethereum wallet.Report incorrect code
Copy
Ask AI
signMessage: async ({walletId: string, message: string, idempotencyKey?: string}) => Promise<{signature: string, encoding: 'hex'}>
Usage
Report incorrect code
Copy
Ask AI
const {signature, encoding} = await privy.walletApi.ethereum.signMessage({
walletId: 'insert-wallet-id',
message: 'Hello world'
});
Parameters
Unique ID of the wallet to take actions with.
The string or bytes to sign with the wallet.
Idempotency key to identify a unique request.
Returns
An encoded string serializing the signature produced by the user’s wallet.
The encoding format for the returned
signature. Currently, only 'hex' is supported for
Ethereum.To sign a message from your wallet, use the
signMessage method.
It will sign your message, and return the signature to you.Usage
Report incorrect code
Copy
Ask AI
try {
String message = "Hello, Ethereum.";
// Example: If wallet's owner is an authorization private key
AuthorizationContext authorizationContext = AuthorizationContext.builder()
.addAuthorizationPrivateKey("authorization-key")
.build();
EthereumPersonalSignRpcResponseData response = privyClient
.wallets()
.ethereum()
.signMessage(
walletId,
message.getBytes(StandardCharsets.UTF_8),
authorizationContext
);
String signature = response.signature();
} catch (APIException e) {
String errorBody = e.bodyAsString();
System.err.println(errorBody);
} catch (Exception e) {
System.err.println(e.getMessage());
}
Parameters
When signing a message with your Ethereum wallet, you can sign over the raw bytes of the message or a hex string encoding.The raw bytes of the message to sign over.
Alternatively, a hex string encoding of the message to sign over.
Returns
TheEthereumPersonalSignRpcResponseData object contains a signature() fieldThe signature produced by the wallet.
Use the
sign_message method on the Ethereum service to sign a UTF-8 message with an Ethereum wallet.Usage
Report incorrect code
Copy
Ask AI
use privy_rs::{AuthorizationContext, PrivyClient};
let client = PrivyClient::new("app_id".to_string(), "app_secret".to_string())?;
let ethereum_service = client.wallets().ethereum();
let auth_ctx = AuthorizationContext::new();
let signature = ethereum_service
.sign_message(
&wallet_id,
"Hello, Ethereum!",
&auth_ctx,
Some("unique-request-id-123"),
)
.await?;
println!("Message signed successfully");
Parameters and Returns
See the Rust SDK documentation for detailed parameter and return types, including embedded examples:For REST API details, see the API reference.To sign a message make a POST request to
Report incorrect code
Copy
Ask AI
https://api.privy.io/v1/wallets/<wallet_id>/rpc
Parameters
RPC method to execute with the wallet.
Parameters for the RPC method to execute with the wallet.
Returns
The RPC method executed with the wallet.
Usage
Report incorrect code
Copy
Ask AI
$ curl --request POST https://api.privy.io/v1/wallets/<wallet_id>/rpc \
-u "<your-privy-app-id>:<your-privy-app-secret>" \
-H "privy-app-id: <your-privy-app-id>" \
-H "privy-authorization-signature: <authorization-signature-for-request>" \
-H 'Content-Type: application/json' \
-d '{
"chain_type": "ethereum",
"method": "personal_sign",
"params": {
"message": "Hello, Ethereum.",
"encoding": "utf-8"
}
}'
Looking to send USDC or another ERC-20 token? See our Send USDC recipe.

