Skip to content

Requesting signatures and transactions

To request signatures or transactions from a connected wallet, you can either:

  • use the wallet's EIP-1193 provider to send JSON-RPC requests to the wallet directly
  • pass the wallet to a library like viem, ethers, or wagmi
  • for the embedded wallet specifically, use Privy's native signMessage and sendTransaction methods to customize the signature and transaction prompts for users

The guide below explains how to request signatures and transactions via the EIP-1193 provider directly.

The request method

At a high-level, the EIP-1193 provider implements a method called request that accepts an object with the following fields:

  • method: the name of a JSON-RPC request to send to the wallet (e.g. 'personal_sign')
  • params: any parameters to include with the request

You can use the request method to interface with the wallet per the instructions below.

Signatures

To request a signature from a wallet, first find your desired wallet from the wallets array and get its EIP-1193 provider via its getEthereumProvider method:

tsx
const {wallets} = useWallets();
const wallet = wallets[0]; // Replace this with your desired wallet
const provider = await wallet.getEthereumProvider();

Then, using the provider's request method, send a personal_sign JSON-RPC to the wallet. In the params array, include the message to sign as the first entry, and the wallet's address as the second entry.

tsx
const address = wallet.address;
const message = 'This is the message I am signing';
const signature = await provider.request({
  method: 'personal_sign',
  params: [message, address],
});

If you've integrated Privy with another web3 library, you can also use that library's syntax for requesting a signature from the wallet:

LibraryMethod
ViemUse the wallet client's signMessage method.
EthersUse the signer's signMessage method.
WagmiUse the useSignMessage hook.
Privy tip
When requesting a signature from an embedded wallet, you can customize the signature prompt by using Privy's native signMessage method.

Transactions

To request a transaction from a wallet, first find your desired wallet from the wallets array and get its EIP-1193 provider via its getEthereumProvider method:

tsx
const {wallets} = useWallets();
const wallet = wallets[0]; // Replace this with your desired wallet
const provider = await wallet.getEthereumProvider();

Then, using the provider's request method, send a eth_sendTransaction JSON-RPC to the wallet. In the params array, include as the first entry an object containing the transaction's parameters, such as to, value, data, gasLimit, maxPriorityFeePerGas, maxFeePerGas, and gasPrice.

tsx
const transactionRequest = {
  to: '0xTheRecipientAddress',
  value: 100000,
};
const transactionHash = await provider.request({
  method: 'eth_sendTransaction',
  params: [transactionRequest],
});

See these docs for the parameters that can be passed in eth_sendTransaction.

If you've integrated Privy with another web3 library, you can also use that library's syntax for requesting a transaction from the wallet:

LibraryMethod
ViemUse the wallet client's sendTransaction method.
EthersUse the signer's sendTransaction method.
WagmiUse the useSendTransaction hook.
Privy tip
When requesting a transaction from an embedded wallet, you can customize the transaction prompt by using Privy's native sendTransaction method.

Smart contracts

Calling a smart contract is a special case of sending a transaction. To call a smart contract, you should send a transaction with the following parameters in the transaction request:

  • to: the address of the smart contract to call
  • data: any calldata to pass as part of the smart contract call
  • value: any value to send from the user's wallet to the smart contract

To prepare the calldata for a smart contract interaction, we recommend using viem's encodeFunctionData method, like so:

tsx
import {encodeFunctionData} from 'viem';
...
const data = encodeFunctionData({
    abi: insertYourContractAbiAsJson
    functionName: 'insertTheNameOfTheMethodToCall'
})

You can then send a transaction from the wallet as normal, and pass the calldata in the data field of the transaction request:

tsx
const transactionRequest = {
  to: '0xTheContractAddress',
  data: data,
  value: 100000, // Only necessary for payable methods
};
const transactionHash = await provider.request({
  method: 'eth_sendTransaction',
  params: [transactionRequest],
});