
Security News
The Hidden Blast Radius of the Axios Compromise
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.
ChainWise.js is a powerful, fast, multi-blockchain HD wallet library that provides seamless cryptocurrency operations across 17+ blockchain networks. Built with a unified architecture, it eliminates the complexity of managing separate crypto libraries while providing enterprise-grade security and performance.
| Tier | Networks | Status |
|---|---|---|
| Tier 1 | Bitcoin, Ethereum, Solana, Cardano, Polkadot, Kusama, Avalanche | ✅ Production |
| Tier 2 | Binance Smart Chain, Polygon, Cosmos, NEAR, Tron | ✅ Production |
| Tier 3 | Algorand, Stellar, Ripple, Litecoin, Monero, Filecoin, Nostr | ⚡ Active Development |
# npm
npm install chainwise
# yarn
yarn add chainwise
# pnpm
pnpm add chainwise
<!-- Production -->
<script src="https://cdn.jsdelivr.net/npm/chainwise@latest/dist/chainwise.min.js"></script>
<!-- Development -->
<script src="https://unpkg.com/chainwise@latest/dist/chainwise.js"></script>
import ChainWise from 'chainwise';
// Initialize the wallet
const wallet = new ChainWise({
maxWorkers: 4,
enableLogging: true,
autoSave: true
});
// Create a new wallet
await wallet.initialize('your-secure-password');
// Get addresses for all supported networks
const addresses = wallet.getAllAddresses();
console.log(addresses);
// {
// bitcoin: { legacy: '1A1zP1...', segwit: 'bc1qw508d...' },
// ethereum: '0x742d35Cc...',
// solana: '9WzDXwBbmkg8...',
// ...
// }
// Sign a message
const signature = await wallet.signMessage('Hello ChainWise!', 'bitcoin');
console.log(signature);
// Verify the signature
const isValid = await wallet.verifyMessage('Hello ChainWise!', signature);
console.log('Signature valid:', isValid.isValid);
const wallet = new ChainWise();
// 1. Initialize with password (creates new wallet if none exists)
await wallet.initialize('secure-password');
// 2. Use wallet operations
const addresses = wallet.getAllAddresses();
const signature = await wallet.signMessage('test', 'ethereum');
// 3. Lock when not in use
wallet.lock();
// 4. Unlock when needed
await wallet.unlock('secure-password');
// 5. Clear/destroy when done
await wallet.clearWallet();
wallet.destroy();
// Export seed for backup
const seed = wallet.exportSeed();
console.log('Backup this seed:', seed);
// Import from existing seed
await wallet.importSeed('a1b2c3d4e5f6...', 'new-password');
// Export encrypted wallet data
const backup = await wallet.exportWallet('backup-password');
// Import encrypted wallet data
await wallet.importWallet(backup, 'backup-password');
// Generate 50 Bitcoin addresses
const addresses = await wallet.generateMultipleAddresses('bitcoin', 50, 0);
addresses.forEach(addr => {
console.log(`Index ${addr.index}: ${addr.legacy} / ${addr.segwit}`);
});
// Export to CSV
wallet.exportBulkAddresses('bitcoin', addresses);
// Get network configurations
const networks = wallet.getSupportedNetworks();
networks.forEach(network => {
console.log(`${network.name}: ${network.curve} curve, Tier ${network.tier}`);
});
// Get specific network info
const bitcoinInfo = wallet.getNetworkWalletInfo('bitcoin');
console.log(bitcoinInfo);
// {
// network: 'Bitcoin',
// symbol: 'BTC',
// curve: 'secp256k1',
// address: { legacy: '...', segwit: '...' },
// explorer: 'https://blockstream.info'
// }
// Get performance metrics
const metrics = wallet.getMetrics();
console.log('Average response time:', metrics.averageResponseTime);
console.log('Success rate:', metrics.successRate);
// Get wallet statistics
const stats = wallet.getWalletStats();
console.log('Total operations:', stats.performance.totalOperations);
console.log('Active workers:', stats.workers.activeWorkers);
// Listen for wallet events
window.addEventListener('ChainWise:walletReady', (event) => {
console.log('Wallet is ready!', event.detail);
});
window.addEventListener('ChainWise:walletLocked', (event) => {
console.log('Wallet locked for security');
});
window.addEventListener('ChainWise:walletUnlocked', (event) => {
console.log('Wallet unlocked and ready');
});
const wallet = new ChainWise({
// Worker configuration
maxWorkers: 4, // Max concurrent workers
workerTimeout: 30000, // Worker timeout in ms
// Security settings
autoSave: true, // Auto-save to IndexedDB
enableLogging: true, // Enable console logging
// Network selection
defaultNetworks: ['bitcoin', 'ethereum', 'solana'], // Limit networks
// Performance tuning
maxCacheSize: 1000, // Max cached operations
cacheTTL: 300000 // Cache TTL in ms
});
ChainWise enforces strong password requirements:
const validation = wallet.validatePassword('mypassword');
console.log(validation);
// {
// isValid: false,
// score: 2,
// issues: [
// 'Password must contain uppercase letters',
// 'Password must contain numbers',
// 'Password must contain special characters'
// ]
// }
// Always backup your seed phrase securely
const seed = wallet.exportSeed(); // Store this safely offline
// Create encrypted backups
const backup = await wallet.exportWallet('backup-password');
// Store backup in secure location (not on same device)
// Verify backup integrity
const verification = await wallet.importWallet(backup, 'backup-password');
console.log('Backup valid:', verification.success);
| Browser | Version | Status |
|---|---|---|
| Chrome | 88+ | ✅ Full Support |
| Firefox | 85+ | ✅ Full Support |
| Safari | 14+ | ✅ Full Support |
| Edge | 88+ | ✅ Full Support |
| Opera | 74+ | ✅ Full Support |
| Mobile Safari | 14+ | ✅ Full Support |
| Chrome Mobile | 88+ | ✅ Full Support |
import React, { useEffect, useState } from 'react';
import ChainWise from 'chainwise';
function WalletComponent() {
const [wallet] = useState(() => new ChainWise());
const [addresses, setAddresses] = useState({});
const [isLocked, setIsLocked] = useState(true);
useEffect(() => {
const handleWalletReady = () => {
setAddresses(wallet.getAllAddresses());
setIsLocked(wallet.isLocked);
};
window.addEventListener('ChainWise:walletReady', handleWalletReady);
window.addEventListener('ChainWise:walletUnlocked', handleWalletReady);
return () => {
window.removeEventListener('ChainWise:walletReady', handleWalletReady);
window.removeEventListener('ChainWise:walletUnlocked', handleWalletReady);
wallet.destroy();
};
}, [wallet]);
const initWallet = async () => {
await wallet.initialize('secure-password');
};
return (
<div>
<h2>ChainWise Wallet</h2>
{isLocked ? (
<button onClick={initWallet}>Initialize Wallet</button>
) : (
<div>
<h3>Your Addresses:</h3>
{Object.entries(addresses).map(([network, address]) => (
<div key={network}>
<strong>{network}:</strong> {typeof address === 'object' ? address.segwit || address.legacy : address}
</div>
))}
</div>
)}
</div>
);
}
<template>
<div>
<h2>ChainWise Wallet</h2>
<button v-if="isLocked" @click="initWallet">Initialize Wallet</button>
<div v-else>
<h3>Your Addresses:</h3>
<div v-for="(address, network) in addresses" :key="network">
<strong>{{ network }}:</strong>
{{ typeof address === 'object' ? (address.segwit || address.legacy) : address }}
</div>
</div>
</div>
</template>
<script>
import ChainWise from 'chainwise';
export default {
data() {
return {
wallet: new ChainWise(),
addresses: {},
isLocked: true
};
},
async mounted() {
window.addEventListener('ChainWise:walletReady', this.handleWalletReady);
window.addEventListener('ChainWise:walletUnlocked', this.handleWalletReady);
},
beforeUnmount() {
window.removeEventListener('ChainWise:walletReady', this.handleWalletReady);
window.removeEventListener('ChainWise:walletUnlocked', this.handleWalletReady);
this.wallet.destroy();
},
methods: {
async initWallet() {
await this.wallet.initialize('secure-password');
},
handleWalletReady() {
this.addresses = this.wallet.getAllAddresses();
this.isLocked = this.wallet.isLocked;
}
}
};
</script>
const ChainWise = require('chainwise');
// Node.js usage
const wallet = new ChainWise({
maxWorkers: 2, // Fewer workers in Node.js
enableLogging: false // Disable browser-specific logging
});
async function main() {
await wallet.initialize('server-password');
const addresses = wallet.getAllAddresses();
console.log('Generated addresses:', addresses);
// Sign a transaction
const signature = await wallet.signMessage('server-message', 'bitcoin');
console.log('Signature:', signature);
wallet.destroy();
}
main().catch(console.error);
try {
await wallet.initialize('password');
} catch (error) {
if (error.message.includes('Password validation failed')) {
console.log('Please use a stronger password');
} else if (error.message.includes('Invalid seed')) {
console.log('The provided seed is invalid');
} else {
console.error('Wallet error:', error.message);
}
}
// Handle worker errors
wallet.on('workerError', (error) => {
console.error('Worker failed:', error);
// Implement fallback or retry logic
});
// Pre-initialize for better performance
const wallet = new ChainWise({
maxWorkers: 8, // Use more workers for better parallel processing
defaultNetworks: ['bitcoin', 'ethereum'], // Limit to needed networks
});
// Batch operations when possible
const operations = await Promise.all([
wallet.generateMultipleAddresses('bitcoin', 10),
wallet.generateMultipleAddresses('ethereum', 10),
wallet.signMessage('message1', 'bitcoin'),
wallet.signMessage('message2', 'ethereum')
]);
// Use caching for repeated operations
const cachedAddresses = wallet.getAllAddresses(); // Cached after first call
// Clean up resources
wallet.destroy(); // Terminates workers and clears memory
// Monitor memory usage
const stats = wallet.getWalletStats();
console.log('Memory usage:', stats.workers);
// Clear caches periodically
wallet.clearCache(); // If available in your version
// Check if Web Workers are supported
if (typeof Worker === 'undefined') {
console.warn('Web Workers not supported, using main thread');
const wallet = new ChainWise({ maxWorkers: 0 }); // Disable workers
}
// Check network support before operations
const supportedNetworks = wallet.getSupportedNetworks();
const isNetworkSupported = supportedNetworks.some(n => n.key === 'bitcoin' && n.isSupported);
if (!isNetworkSupported) {
throw new Error('Bitcoin network not supported in this version');
}
// Handle storage quota exceeded
try {
await wallet.initialize('password');
} catch (error) {
if (error.message.includes('storage')) {
// Clear old data or ask user to free space
await wallet.clearWallet();
}
}
MIT License - see the LICENSE file for details.
Built with ❤️ by Omodaka9375
Making multi-blockchain development simple and secure
FAQs
Universal Multi-Blockchain HD Wallet Library for the Browser
We found that chainwise demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.