Appearance
Using wallets on EVM networks
You can use Privy server wallets to sign messages and execute transactions on any EVM-compatible network, like Ethereum, Base, or Arbitrum.
Using the SDK
TIP
If you're familiar with the viem
library for using wallets on EVM networks, you can integrate Privy server wallets directly with viem
.
To execute an EVM action with a server wallet, use the methods on PrivyClient
's walletApi.ethereum
class.
There are currently four supported EVM actions: signMessage
, signTypedData
, signTransaction
, and sendTransaction
. View the parameters required for each method and examples below.
INFO
The walletApi.ethereum
methods above respectively correspond to the EIP1193 personal_sign
, eth_signTypedData_v4
, eth_signTransaction
, and eth_sendTransaction
methods.
Field | Type | Description |
---|---|---|
walletId | string | Unique ID of the wallet to take actions with. |
idempotencyKey | string | (Optional) Idempotency key to identify a unique request. |
message | string | Uint8Array | The string or bytes to sign with the wallet. |
tsx
const {data} = await privy.walletApi.ethereum.signMessage({
walletId: 'insert-wallet-id',
message: 'Hello world',
});
// Get the signature and encoding from the response
const {signature, encoding} = data;
Using the REST API
To request a signature or transaction from an Ethereum wallet, make a POST
request to:
sh
https://api.privy.io/v1/wallets/<wallet_id>/rpc
TIP
In the request headers, make sure to include Privy's required authentication headers and headers that may be required for your app's wallet API setup.
Body
In the body of the request, include the following fields. Make sure to follow the appropriate guidance for the action you'd like to take with the wallet (signing messages, signing typed data, signing transactions, or signing and broadcasting transactions).
Field | Type | Description |
---|---|---|
method | 'personal_sign' | RPC method to execute with the wallet. |
params | Object | Parameters for the RPC method to execute with the wallet. |
params.message | string | The message to sign with the wallet. If the message to sign is raw bytes, you must serialize the message as a hexadecimal string. |
params.encoding | 'utf-8' | 'hex' | The encoding format for params.message . Use utf-8 for a string message and hex for bytes. |
Response
If the action is allowed, Privy will send the following fields in the response body:
Field | Type | Description |
---|---|---|
method | 'personal_sign' | The RPC method executed with the wallet. |
data | Object | Outputs for the RPC method executed with the wallet. |
data.signature | string | An encoded string serializing the signature produced by the user's wallet. |
data.encoding | 'hex' | The encoding format for the returned signature . Currently, only 'hex' is supported for Ethereum. |
Examples
As an example, a sample request to take a delegated action with a wallet might look like the following:
bash
$ 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"
}
}'
A successful response will look like the following:
json
{
"method": "personal_sign",
"data": {
"signature": "0x28eac519bf4051a624d4246a5788667baf84dcd7d2a439b314b339013b5cdb4c",
"encoding": "hex"
}
}
Using viem
viem
is a popular TypeScript library on EVM for executing onchain actions with wallets. Privy's server wallets on EVM natively integrate with viem
, allowing you to use the library's interfaces for signing messages, signing typed data, sending transactions, and more.
To integrate with viem
, first install version 2^
of the library as a peer dependency:
sh
npm i viem@latest
Then, use Privy's createViemAccount
method to initialize an instance of a viem Account
for an EVM server wallet. As a parameter to this method, pass an object with the following:
Field | Type | Description |
---|---|---|
walletId | string | ID of the wallet. |
address | 0x${string} | Ethereum address of the wallet. |
privy | PrivyClient | Instance of the Privy client for your app. |
As an example, you can initialize an Account
like so:
tsx
import {PrivyClient} from '@privy-io/server-auth';
import {createViemAccount} from '@privy-io/server-auth/viem';
// Initialize your Privy client
const privy = new PrivyClient(...);
// Create a viem account instance for a wallet
const account = await createViemAccount({
walletId: 'insert-wallet-id',
address: 'insert-address',
privy
});
From the returned Account
, you can then initialize a viem WalletClient
to sign messages and execute transactions with the wallet like so:
tsx
import {createWalletClient, http, parseEther} from 'viem';
import {base} from 'viem/chains';
const client = createWalletClient({
account, // `Account` instance from above
chain: base, // Replace with your desired network
transport: http(),
});
const hash = await client.sendTransaction({
to: '0x59D3eB21Dd06A211C89d1caBE252676e2F3F2218',
value: parseEther('0.001'),
});