Private Key Access
Overview
The Node.js SDK provides direct access to user private keys, enabling integration with any blockchain network. This is a key feature that makes the SDK suitable for backend and programmatic use cases.
Security Notice
Private keys provide full control over user assets. Handle them securely:
- Never log private keys
- Store them encrypted if persistence is needed
- Use secure memory handling
- Implement proper access controls
Available Methods
The provider offers different methods to access private keys depending on your blockchain needs:
Method | Description | Use Case |
---|---|---|
eth_private_key | Ethereum-formatted private key | EVM chains (Ethereum, Polygon, BSC, etc.) |
solanaPrivateKey | Solana private key | Solana blockchain |
private_key | Raw private key | Any blockchain |
EVM Chains (Ethereum, Polygon, BSC, etc.)
Get Ethereum Private Key
const privateKey = await provider.request({ method: 'eth_private_key' })
console.log('Private Key:', privateKey) // 0x1234567890abcdef...
Use with Ethers.js
const { ethers } = require('ethers')
// Get private key
const privateKey = await provider.request({ method: 'eth_private_key' })
// Create wallet instance
const wallet = new ethers.Wallet(privateKey)
// Connect to a provider
const rpcProvider = new ethers.providers.JsonRpcProvider('https://rpc.ankr.com/eth')
const connectedWallet = wallet.connect(rpcProvider)
// Get address
const address = await connectedWallet.getAddress()
console.log('Wallet Address:', address)
// Sign a transaction
const tx = {
to: '0x742d35Cc6635C0532925a3b8138341B0F7E8a4e8',
value: ethers.utils.parseEther('0.1'),
}
const signedTx = await connectedWallet.signTransaction(tx)
const receipt = await connectedWallet.sendTransaction(tx)
Use with Viem
const { createWalletClient, createPublicClient, http } = require('viem')
const { privateKeyToAccount } = require('viem/accounts')
const { mainnet } = require('viem/chains')
// Get private key
const privateKey = await provider.request({ method: 'eth_private_key' })
// Create account from private key
const account = privateKeyToAccount(privateKey)
// Create wallet client
const walletClient = createWalletClient({
account,
chain: mainnet,
transport: http('https://rpc.ankr.com/eth'),
})
// Create public client for reading
const publicClient = createPublicClient({
chain: mainnet,
transport: http('https://rpc.ankr.com/eth'),
})
// Send transaction
const hash = await walletClient.sendTransaction({
to: '0x742d35Cc6635C0532925a3b8138341B0F7E8a4e8',
value: parseEther('0.1'),
})
Solana Integration
Get Solana Private Key
const solanaPrivateKey = await provider.request({ method: 'solanaPrivateKey' })
console.log('Solana Private Key:', solanaPrivateKey) // Base58 encoded
Use with Solana Web3.js
const {
Connection,
Keypair,
PublicKey,
Transaction,
SystemProgram,
LAMPORTS_PER_SOL,
} = require('@solana/web3.js')
const bs58 = require('bs58')
// Get private key
const solanaPrivateKey = await provider.request({ method: 'solanaPrivateKey' })
// Create keypair from private key
const secretKey = bs58.decode(solanaPrivateKey)
const keypair = Keypair.fromSecretKey(secretKey)
// Connect to Solana
const connection = new Connection('https://api.mainnet-beta.solana.com')
// Get balance
const balance = await connection.getBalance(keypair.publicKey)
console.log('Balance:', balance / LAMPORTS_PER_SOL, 'SOL')
// Send transaction
const transaction = new Transaction().add(
SystemProgram.transfer({
fromPubkey: keypair.publicKey,
toPubkey: new PublicKey('11111111111111111111111111111112'),
lamports: 0.1 * LAMPORTS_PER_SOL,
})
)
const signature = await connection.sendTransaction(transaction, [keypair])
Other Blockchains
Get Raw Private Key
const rawPrivateKey = await provider.request({ method: 'private_key' })
console.log('Raw Private Key:', rawPrivateKey) // Hex string
Example: Bitcoin Integration
const bitcoin = require('bitcoinjs-lib')
// Get raw private key
const rawPrivateKey = await provider.request({ method: 'private_key' })
// Create Bitcoin keypair
const keyPair = bitcoin.ECPair.fromPrivateKey(Buffer.from(rawPrivateKey.slice(2), 'hex'))
// Get Bitcoin address
const { address } = bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey })
console.log('Bitcoin Address:', address)
Complete Integration Example
Here's a comprehensive example showing multi-chain support:
const { Web3Auth } = require('@web3auth/node-sdk')
const { ethers } = require('ethers')
class MultiChainWallet {
constructor(clientId) {
this.web3auth = new Web3Auth({
clientId,
web3AuthNetwork: 'sapphire_mainnet',
})
}
async initialize() {
await this.web3auth.init()
}
async authenticate(verifier, verifierId, idToken) {
this.provider = await this.web3auth.connect({
verifier,
verifierId,
idToken,
})
}
async getEthereumWallet() {
const privateKey = await this.provider.request({ method: 'eth_private_key' })
return new ethers.Wallet(privateKey)
}
async getSolanaKeypair() {
const { Keypair } = require('@solana/web3.js')
const bs58 = require('bs58')
const solanaPrivateKey = await this.provider.request({ method: 'solanaPrivateKey' })
const secretKey = bs58.decode(solanaPrivateKey)
return Keypair.fromSecretKey(secretKey)
}
async getRawPrivateKey() {
return await this.provider.request({ method: 'private_key' })
}
async getAddresses() {
const [ethWallet, solanaKeypair] = await Promise.all([
this.getEthereumWallet(),
this.getSolanaKeypair(),
])
return {
ethereum: ethWallet.address,
solana: solanaKeypair.publicKey.toString(),
}
}
}
// Usage
const wallet = new MultiChainWallet('YOUR_CLIENT_ID')
await wallet.initialize()
await wallet.authenticate('verifier', 'user@example.com', 'jwt_token')
const addresses = await wallet.getAddresses()
console.log('Addresses:', addresses)
Security Best Practices
1. Secure Memory Handling
// Use Buffer.alloc for sensitive data
function securePrivateKeyHandling(privateKey) {
const keyBuffer = Buffer.from(privateKey.slice(2), 'hex')
try {
// Use the private key
const wallet = new ethers.Wallet(keyBuffer)
return wallet.address
} finally {
// Clear the buffer
keyBuffer.fill(0)
}
}
2. Environment-based Key Access
// Only allow private key access in specific environments
function getPrivateKeySecurely() {
if (process.env.NODE_ENV === 'production' && !process.env.ALLOW_PRIVATE_KEY_ACCESS) {
throw new Error('Private key access not allowed in production')
}
return provider.request({ method: 'eth_private_key' })
}
3. Audit Logging
async function auditedPrivateKeyAccess(userId, purpose) {
console.log(`Private key accessed by ${userId} for ${purpose} at ${new Date().toISOString()}`)
// Log to audit system
await logAuditEvent({
action: 'private_key_access',
userId,
purpose,
timestamp: new Date(),
})
return provider.request({ method: 'eth_private_key' })
}
Disabling Private Key Export
Private key export can be disabled in the Web3Auth Dashboard:
- Go to your project settings
- Navigate to "Advanced Settings"
- Toggle "Disable Private Key Export"
- Save changes
When disabled, private key methods will throw an error:
try {
const privateKey = await provider.request({ method: 'eth_private_key' })
} catch (error) {
console.error('Private key export disabled:', error.message)
}