We refreshed our doc site!
Bookmarked links may have changed
Read release notesThis tutorial walks you through creating a developer-controlled wallet to sign transactions on EVM chains.
You can only create Externally Owned Accounts (EOA) for signing transactions. For details, see the Account Types guide.
Before you begin:
When creating a developer-controlled wallet, pass EVM-TESTNET
or EVM
in the blockchains
field. This wallet can be used to sign transactions on any EVM chain.
The following example code shows how to create a wallet using the Circle Developer SDK.
const response = await circleDeveloperSdk.createWallets({
accountType: 'EOA',
blockchains: ['EVM-TESTNET'],
count: 2,
walletSetId: '<wallet-set-id>'
});
Use count
to specify the number of wallets to create, up to a maximum of 200 per API request.
You can sign a transaction object using the API or SDK.
The following example code shows how to build a transaction object.
const Web3 = require('web3');
const EthereumTx = require('ethereumjs-tx').Transaction;
// Connect to an Ethereum node
const web3 = new Web3('https://mainnet.infura.io/v3/YOUR-PROJECT-ID');
async function buildUnsignedRawTransaction() {
// Sender's address
const senderAddress = '0x1234...'; // Replace with the sender's address
// Recipient's address
const recipientAddress = '0x5678...'; // Replace with the recipient's address
// Amount to send in wei
const amountToSend = web3.utils.toWei('0.1', 'ether');
// Get the nonce
const nonce = await web3.eth.getTransactionCount(senderAddress);
// Estimate gas limit
const estimateGas = await web3.eth.estimateGas({
to: recipientAddress,
value: amountToSend
});
// Get gas price
const gasPrice = await web3.eth.getGasPrice();
// Prepare the transaction object
const txObject = {
nonce: web3.utils.toHex(nonce),
to: recipientAddress,
value: web3.utils.toHex(amountToSend),
gasLimit: web3.utils.toHex(estimateGas),
gasPrice: web3.utils.toHex(gasPrice),
chainId: 1 // 1 for Ethereum mainnet
};
chainId
is a required field that uniquely identifies the blockchain network to ensure your transaction is processed on the intended chain. Use the appropriate chain ID for the network on which you want to build transactions.
The following example code shows how to sign a transaction object.
Transaction object
const responseObject = await circleDeveloperSdk.signTransaction({
walletID: '<wallet-id>',
transaction: txObject, // Pass the transaction object
});
If you have created Programmable Wallets on an EVM-compatible chain such as Ethereum, Polygon, Avalanche, or Arbitrum, an EVM wallet created under the same wallet set maps to the same addresses.
In these cases, it is extremely important that you do not use the EVM wallet to sign transactions for existing Programmable Wallets on those chains; for example, sign transaction with chainID = 137 signs MATIC transaction.
Your Programmable Wallet transactions will be stuck and you are responsible for any resulting consequences.