Skip to main content

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:

MethodDescriptionUse Case
eth_private_keyEthereum-formatted private keyEVM chains (Ethereum, Polygon, BSC, etc.)
solanaPrivateKeySolana private keySolana blockchain
private_keyRaw private keyAny 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:

  1. Go to your project settings
  2. Navigate to "Advanced Settings"
  3. Toggle "Disable Private Key Export"
  4. 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)
}

Next Steps