Multi-chain Bitcoin wallet SDK for RSK, BSC, Lightning swaps, Liquid swaps, and Submarine swaps
bash
npm install @bittasker/wallet-core
`
Quick Start
`typescript
import { WalletManager } from '@bittasker/wallet-core';
// Initialize wallet with mnemonic
const walletManager = new WalletManager({
network: 'testnet',
mnemonic: 'your twelve word mnemonic phrase here...'
});
await walletManager.initialize();
// Get balances
const balances = await walletManager.getBalances();
console.log('RBTC:', balances.rsk.rbtc);
console.log('BNB:', balances.bsc.bnb);
// Send RBTC transaction
const txHash = await walletManager.rskWallet.send(
'0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb',
'0.01'
);
console.log('Transaction:', txHash);
`
Core Concepts
$3
The main class that orchestrates all wallet operations across chains.
`typescript
import { WalletManager } from '@bittasker/wallet-core';
const walletManager = new WalletManager({
network: 'testnet', // 'mainnet', 'testnet', or 'regtest'
mnemonic: 'your mnemonic phrase',
swapStorage: myStorageAdapter // Optional: for swap persistence
});
await walletManager.initialize();
`
$3
- mainnet: Production networks (RSK Mainnet, BSC Mainnet, Bitcoin Mainnet)
- testnet: Test networks (RSK Testnet, BSC Testnet, Bitcoin Testnet)
- regtest: Local development networks
$3
Implement custom storage for swap data persistence:
`typescript
import { SwapStorage } from '@bittasker/wallet-core';
class MyStorage implements SwapStorage {
async save(swapId: string, data: any): Promise {
// Save to your preferred storage
localStorage.setItem( swap-${swapId}, JSON.stringify(data));
}
async load(swapId: string): Promise {
const item = localStorage.getItem( swap-${swapId});
return item ? JSON.parse(item) : null;
}
async loadAll(): Promise {
// Load all swaps
const swaps = [];
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
if (key?.startsWith('swap-')) {
swaps.push(JSON.parse(localStorage.getItem(key)!));
}
}
return swaps;
}
async delete(swapId: string): Promise {
localStorage.removeItem( swap-${swapId});
}
}
// Use with WalletManager
const walletManager = new WalletManager({
network: 'testnet',
mnemonic: 'your mnemonic',
swapStorage: new MyStorage()
});
`
Complete Usage Guide
$3
`typescript
import { WalletManager } from '@bittasker/wallet-core';
// Basic initialization
const walletManager = new WalletManager({
network: 'testnet',
mnemonic: await getSecureMnemonic() // Your secure mnemonic retrieval
});
await walletManager.initialize();
`
$3
`typescript
const addresses = walletManager.getAddresses();
console.log('RSK Address:', addresses.rsk);
console.log('BSC Address:', addresses.bsc);
`
$3
`typescript
// Get all balances
const balances = await walletManager.getBalances();
console.log('RBTC:', balances.rsk.rbtc);
console.log('BNB:', balances.bsc.bnb);
// Get RSK balance directly
const rskBalance = await walletManager.rskWallet.getBalance();
console.log('Balance:', rskBalance.formatted, 'RBTC');
console.log('Raw:', rskBalance.balance.toString(), 'wei');
// Get BSC balances
const bscBalances = await walletManager.bscWallet.getBalances();
console.log('BNB:', bscBalances.bnb.formatted);
console.log('USDT:', bscBalances.usdt.formatted);
`
$3
#### Send RBTC
`typescript
try {
const txHash = await walletManager.rskWallet.send(
'0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb',
'0.01' // Amount in RBTC
);
console.log('Transaction sent:', txHash);
} catch (error) {
console.error('Transaction failed:', error);
}
`
#### Send BNB
`typescript
const txHash = await walletManager.bscWallet.sendBNB(
'0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb',
'0.1' // Amount in BNB
);
`
#### Send USDT
`typescript
const txHash = await walletManager.bscWallet.sendUSDT(
'0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb',
'100' // Amount in USDT
);
`
$3
`typescript
// Load RSK transactions (returns raw API format)
const rskTxs = await walletManager.rskWallet.loadTransactions();
rskTxs.forEach(tx => {
console.log('Hash:', tx.hash);
console.log('From:', tx.from.hash); // Address objects
console.log('To:', tx.to.hash);
console.log('Value:', tx.value);
console.log('Status:', tx.status); // "ok" or error status
console.log('Timestamp:', tx.timestamp); // ISO 8601 format
console.log('Method:', tx.method); // Contract method if applicable
});
// Load BSC transactions (returns same raw API format)
const bscTxs = await walletManager.bscWallet.loadTransactions();
bscTxs.forEach(tx => {
console.log('Hash:', tx.hash);
console.log('From:', tx.from.hash); // Same structure
console.log('To:', tx.to.hash);
console.log('Value:', tx.value);
console.log('Status:', tx.status);
console.log('Method:', tx.method);
});
`
$3
Swap Lightning BTC to RBTC:
`typescript
// Create reverse swap
const swap = await walletManager.reverseSwapService.createReverseSwap({
amountSats: 100000, // Amount in satoshis
rbtcAddress: walletManager.rskWallet.getAddress(),
walletSigner: walletManager.rskWallet.getWallet()
});
console.log('Pay this Lightning invoice:', swap.invoice);
console.log('Swap ID:', swap.swapId);
// Monitor swap status
const status = await walletManager.reverseSwapService.getSwapStatus(swap.swapId);
console.log('Status:', status);
`
$3
Swap Liquid BTC to RBTC:
`typescript
// Create chain swap
const swap = await walletManager.chainSwapService.createChainSwap({
amountSats: 100000, // Amount in satoshis
rbtcAddress: walletManager.rskWallet.getAddress(),
walletSigner: walletManager.rskWallet.getWallet()
});
console.log('Send L-BTC to:', swap.lockupAddress);
console.log('Swap ID:', swap.swapId);
// Monitor swap status
const status = await walletManager.chainSwapService.getSwapStatus(swap.swapId);
`
$3
Swap RBTC (or BTC/L-BTC) to Lightning:
`typescript
// Get available submarine swap pairs
const pairs = await walletManager.submarineSwapService.getSubmarineSwapPairs();
console.log('Available pairs:', pairs);
// Create submarine swap with Lightning invoice
const invoice = 'lnbc...'; // Lightning invoice to be paid
const { swapId, swapData } = await walletManager.submarineSwapService.createSubmarineSwap({
from: 'RBTC',
to: 'BTC', // Lightning (represented as BTC in Boltz API)
invoice: invoice
});
console.log('Swap created:', swapId);
console.log('Expected amount:', swapData.fromAmount, 'sats');
// Lock RBTC in EtherSwap contract
const rskWallet = walletManager.getRSKWallet();
const { txHash } = await walletManager.submarineSwapService.lockFundsEVM(
swapData,
rskWallet
);
console.log('✅ Funds locked! Transaction:', txHash);
console.log('Boltz will now pay the Lightning invoice');
// Monitor swap status
const currentSwap = walletManager.submarineSwapService.getSwap(swapId);
console.log('Current status:', currentSwap?.status);
// Possible statuses:
// - 'swap.created': Waiting for lockup
// - 'transaction.mempool': Lockup detected
// - 'transaction.confirmed': Lockup confirmed
// - 'invoice.paid': Boltz paid the invoice ✅
`
$3
`typescript
const limits = await walletManager.getSwapLimits();
console.log('Reverse swap (Lightning → RBTC):');
console.log(' Min:', limits.lightning.minimal, 'sats');
console.log(' Max:', limits.lightning.maximal, 'sats');
console.log('Chain swap (L-BTC → RBTC):');
console.log(' Min:', limits.liquid.minimal, 'sats');
console.log(' Max:', limits.liquid.maximal, 'sats');
console.log('Submarine swap (RBTC → Lightning):');
console.log(' Min:', limits.submarine.minimal, 'sats');
console.log(' Max:', limits.submarine.maximal, 'sats');
`
Network Configuration
$3
`typescript
// Uses default RPC endpoints for the network
const walletManager = new WalletManager({
network: 'mainnet',
mnemonic: 'your mnemonic'
});
`
$3
`typescript
const walletManager = new WalletManager({
network: 'mainnet',
mnemonic: 'your mnemonic',
rskConfig: {
rpcUrl: 'https://custom-rsk-node.com',
explorerApiUrl: 'https://custom-explorer.com/api'
},
bscConfig: {
rpcUrl: 'https://custom-bsc-node.com',
explorerApiUrl: 'https://custom-explorer.com/api'
}
});
`
Advanced Usage
$3
Access underlying ethers.js wallets for advanced operations:
`typescript
// Get RSK wallet (ethers.Wallet)
const rskWallet = walletManager.getRSKWallet();
// Get BSC wallet (ethers.Wallet)
const bscWallet = walletManager.getBSCWallet();
// Use for custom transactions
const tx = await rskWallet.sendTransaction({
to: '0x...',
value: ethers.parseEther('0.01'),
gasLimit: 21000
});
`
$3
`typescript
import { ethers } from 'ethers';
const provider = walletManager.rskWallet.getProvider();
const wallet = walletManager.rskWallet.getWallet();
// Estimate gas for transaction
const gasEstimate = await provider.estimateGas({
from: wallet.address,
to: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb',
value: ethers.parseEther('0.01')
});
console.log('Estimated gas:', gasEstimate.toString());
`
$3
`typescript
try {
const txHash = await walletManager.rskWallet.send(recipientAddress, amount);
console.log('Success:', txHash);
} catch (error) {
if (error.message.includes('insufficient funds')) {
console.error('Not enough balance');
} else if (error.message.includes('invalid address')) {
console.error('Invalid recipient address');
} else {
console.error('Transaction failed:', error.message);
}
}
`
Framework Examples
$3
`javascript
import { WalletManager } from '@bittasker/wallet-core';
const walletManager = new WalletManager({
network: 'testnet',
mnemonic: 'your mnemonic'
});
await walletManager.initialize();
// Update UI with balance
const balances = await walletManager.getBalances();
document.getElementById('balance').textContent = balances.rsk.rbtc;
`
$3
`typescript
import { useState, useEffect } from 'react';
import { WalletManager } from '@bittasker/wallet-core';
function WalletComponent() {
const [balance, setBalance] = useState('0');
const [walletManager, setWalletManager] = useState(null);
useEffect(() => {
async function initWallet() {
const manager = new WalletManager({
network: 'testnet',
mnemonic: await getSecureMnemonic()
});
await manager.initialize();
setWalletManager(manager);
const balances = await manager.getBalances();
setBalance(balances.rsk.rbtc);
}
initWallet();
}, []);
return Balance: {balance} RBTC;
}
`
$3
`typescript
import { ref, onMounted } from 'vue';
import { WalletManager } from '@bittasker/wallet-core';
export default {
setup() {
const balance = ref('0');
const walletManager = ref(null);
onMounted(async () => {
walletManager.value = new WalletManager({
network: 'testnet',
mnemonic: await getSecureMnemonic()
});
await walletManager.value.initialize();
const balances = await walletManager.value.getBalances();
balance.value = balances.rsk.rbtc;
});
return { balance };
}
};
`
$3
`svelte
Balance: {balance} RBTC
`
API Reference
$3
Main wallet orchestration class.
Constructor:
`typescript
new WalletManager(config: WalletManagerConfig)
`
Methods:
- initialize(): Promise - Initialize all wallet connections
- getBalances(): Promise - Get all wallet balances
- getAddresses(): { rsk: string; bsc: string } - Get wallet addresses
- getSwapLimits(): Promise - Get swap limits
- getRSKWallet(): Signer - Get RSK wallet for advanced use
- getBSCWallet(): Signer - Get BSC wallet for advanced use
- dispose(): Promise - Clean up resources
Properties:
- rskWallet: RSKWallet - RSK wallet instance
- bscWallet: BSCWallet - BSC wallet instance
- reverseSwapService: ReverseSwapService - Lightning swap service
- chainSwapService: ChainSwapService - Liquid swap service
$3
Rootstock (RSK) wallet operations.
Methods:
- initialize(mnemonic: string): Promise - Initialize wallet
- getAddress(): string - Get wallet address
- getBalance(): Promise<{ balance: bigint; formatted: string }> - Get balance
- send(to: string, amount: string): Promise - Send RBTC
- loadTransactions(): Promise - Load transaction history
- getProvider(): JsonRpcProvider - Get ethers provider
- getWallet(): Wallet - Get ethers wallet
- disconnect(): void - Disconnect wallet
$3
Binance Smart Chain wallet operations.
Methods:
- initialize(mnemonic: string): Promise - Initialize wallet
- getAddress(): string - Get wallet address
- getBalances(): Promise<{ bnb: BalanceInfo; usdt: BalanceInfo }> - Get balances
- sendBNB(to: string, amount: string): Promise - Send BNB
- sendUSDT(to: string, amount: string): Promise - Send USDT
- loadTransactions(): Promise - Load transaction history
- getProvider(): JsonRpcProvider - Get ethers provider
- getWallet(): Wallet - Get ethers wallet
- disconnect(): void - Disconnect wallet
$3
Lightning Network to RBTC swaps.
Methods:
- createReverseSwap(params): Promise - Create reverse swap
- getSwapStatus(swapId: string): Promise - Get swap status
- getSwapLimits(): Promise<{ minimal: number; maximal: number }> - Get limits
$3
Liquid Network to RBTC swaps.
Methods:
- createChainSwap(params): Promise - Create chain swap
- getSwapStatus(swapId: string): Promise - Get swap status
- getSwapLimits(): Promise<{ minimal: number; maximal: number }> - Get limits
TypeScript Support
Full TypeScript support with comprehensive type definitions:
`typescript
import type {
WalletManagerConfig,
WalletBalances,
SwapLimits,
Transaction,
NetworkType,
SwapStorage
} from '@bittasker/wallet-core';
`
Security Best Practices
$3
`typescript
// ❌ BAD: Never hardcode mnemonics
const mnemonic = 'word1 word2 word3...';
// ✅ GOOD: Use secure storage
const mnemonic = await SecureStore.getItemAsync('wallet_mnemonic');
// ✅ GOOD: Use biometric protection
const mnemonic = await getWithBiometric('wallet_mnemonic');
`
$3
`typescript
import { ethers } from 'ethers';
// Always validate addresses before sending
if (!ethers.isAddress(recipientAddress)) {
throw new Error('Invalid address');
}
const txHash = await walletManager.rskWallet.send(recipientAddress, amount);
`
$3
`typescript
// Always test on testnet first
const walletManager = new WalletManager({
network: 'testnet', // Use testnet for testing
mnemonic: 'your mnemonic'
});
`
$3
1. Never expose mnemonics: Always use secure storage for seed phrases
2. Validate addresses: Use ethers.isAddress() before sending transactions
3. Test on testnet: Always test thoroughly on testnet before mainnet
4. Backup mnemonics: Ensure users backup their 12-word recovery phrase
5. Use hardware wallets: For production apps with significant funds
6. Keep dependencies updated: Regularly update to latest SDK version
7. Encrypt sensitive data: Use proper encryption for stored credentials
Troubleshooting
$3
`typescript
// Use custom RPC endpoint
const walletManager = new WalletManager({
network: 'mainnet',
mnemonic: 'your mnemonic',
rskConfig: {
rpcUrl: 'https://your-custom-rsk-node.com'
}
});
`
$3
`typescript
try {
await walletManager.rskWallet.send(to, amount);
} catch (error) {
if (error.message.includes('insufficient')) {
console.error('Not enough balance');
} else if (error.message.includes('gas')) {
console.error('Gas estimation failed');
} else {
console.error('Transaction failed:', error.message);
}
}
`
$3
`typescript
// Reload balances after transaction
const txHash = await walletManager.rskWallet.send(to, amount);
// Wait for confirmation
await new Promise(resolve => setTimeout(resolve, 5000));
// Reload balance
const balance = await walletManager.rskWallet.getBalance();
console.log('Updated balance:', balance.formatted);
``