Cross-Chain Integration: Building with VFX and Bitcoin
Esta página aún no está disponible en tu idioma.
This guide explores how to build applications that leverage both VerifiedX and Bitcoin networks. As a Bitcoin sidechain, VerifiedX enables powerful cross-chain functionality that opens up new possibilities for decentralized applications.
Prerequisites
Section titled “Prerequisites”- Understanding of VFX Basics
- Understanding of Bitcoin Basics
- Familiarity with blockchain concepts
Understanding the VFX-Bitcoin Relationship
Section titled “Understanding the VFX-Bitcoin Relationship”VerifiedX operates as both a standalone blockchain and a Bitcoin sidechain:
- Standalone Operations: Full VFX blockchain functionality
- Sidechain Operations: Bitcoin-compatible transactions and interoperability
- Cross-Chain Features: Seamless integration between both networks
Setting Up Dual Network Support
Section titled “Setting Up Dual Network Support”Initialize both clients for cross-chain operations:
import { VfxClient, btc, Network } from 'vfx-web-sdk';
class CrossChainClient { private vfxClient: VfxClient; private btcClient: btc.BtcClient;
constructor( vfxNetwork: Network = Network.Testnet, btcNetwork: 'mainnet' | 'testnet' = 'testnet' ) { this.vfxClient = new VfxClient(vfxNetwork); this.btcClient = new btc.BtcClient(btcNetwork); }
// Access both clients get vfx() { return this.vfxClient; } get bitcoin() { return this.btcClient; }}
const crossChain = new CrossChainClient(Network.Testnet, 'testnet');Cross-Platform Wallet Generation
Section titled “Cross-Platform Wallet Generation”Create wallets that work across platforms using deterministic generation:
Method 1: Email-Based Deterministic Wallets
Section titled “Method 1: Email-Based Deterministic Wallets”class CrossPlatformWallet { private vfxClient: VfxClient; private btcClient: btc.BtcClient;
constructor(network: 'mainnet' | 'testnet' = 'testnet') { this.vfxClient = new VfxClient(network === 'mainnet' ? Network.Mainnet : Network.Testnet); this.btcClient = new btc.BtcClient(network); }
// Generate wallets that can be recreated on any platform generateCrossPlatformWallet(email: string, password: string, index: number = 0) { // Generate VFX wallet const vfxPrivateKey = this.vfxClient.generatePrivateKey(); const vfxKeypair = { private: vfxPrivateKey, public: this.vfxClient.publicFromPrivate(vfxPrivateKey), address: this.vfxClient.addressFromPrivate(vfxPrivateKey) };
// Generate Bitcoin wallet using email/password for cross-platform compatibility const btcKeypair = this.btcClient.generateEmailKeypair(email, password, index);
return { vfx: vfxKeypair, bitcoin: btcKeypair, credentials: { email, password, index } }; }
// Restore wallets on any platform restoreCrossPlatformWallet(email: string, password: string, index: number = 0) { const btcKeypair = this.btcClient.generateEmailKeypair(email, password, index);
return { bitcoin: btcKeypair, // Note: VFX wallet would need to be restored separately using mnemonic or private key }; }}
// Usageconst walletManager = new CrossPlatformWallet('testnet');const crossWallet = walletManager.generateCrossPlatformWallet( 'user@example.com', 'secure-password-123', 0);
console.log('Cross-platform wallet created:');console.log('VFX Address:', crossWallet.vfx.address);console.log('Bitcoin Address:', crossWallet.bitcoin.address);Method 2: Mnemonic-Based Cross-Chain Wallets
Section titled “Method 2: Mnemonic-Based Cross-Chain Wallets”class MnemonicCrossChainWallet { private vfxClient: VfxClient; private btcClient: btc.BtcClient;
constructor(network: 'mainnet' | 'testnet' = 'testnet') { this.vfxClient = new VfxClient(network === 'mainnet' ? Network.Mainnet : Network.Testnet); this.btcClient = new btc.BtcClient(network); }
// Generate wallets using the same mnemonic generateFromMnemonic(mnemonic?: string, vfxIndex: number = 0, btcIndex: number = 0) { // Use provided mnemonic or generate new one const seed = mnemonic || this.vfxClient.generateMnemonic(12);
// Generate VFX wallet from mnemonic const vfxPrivateKey = this.vfxClient.privateKeyFromMneumonic(seed, vfxIndex); const vfxKeypair = { private: vfxPrivateKey, public: this.vfxClient.publicFromPrivate(vfxPrivateKey), address: this.vfxClient.addressFromPrivate(vfxPrivateKey) };
// Generate Bitcoin wallet from same mnemonic const btcKeypair = this.btcClient.privateKeyFromMnemonic(seed, btcIndex);
return { mnemonic: seed, vfx: vfxKeypair, bitcoin: btcKeypair }; }}
// Usageconst mnemonicWallet = new MnemonicCrossChainWallet('testnet');const crossChainWallet = mnemonicWallet.generateFromMnemonic();
console.log('Mnemonic:', crossChainWallet.mnemonic);console.log('VFX Address:', crossChainWallet.vfx.address);console.log('Bitcoin Address:', crossChainWallet.bitcoin.address);Cross-Chain Account Dashboard
Section titled “Cross-Chain Account Dashboard”Build a unified dashboard showing both VFX and Bitcoin balances:
interface CrossChainAccountInfo { vfx: { address: string; balance: number; domain?: string; txCount: number; }; bitcoin: { address: string; balance: number; balanceBTC: number; txCount: number; addressTypes: any; }; totalValue?: { usd: number; // Would require price API integration };}
class CrossChainDashboard { private vfxClient: VfxClient; private btcClient: btc.BtcClient;
constructor(vfxNetwork: Network, btcNetwork: 'mainnet' | 'testnet') { this.vfxClient = new VfxClient(vfxNetwork); this.btcClient = new btc.BtcClient(btcNetwork); }
async getUnifiedAccountInfo(vfxAddress: string, btcAddress: string): Promise<CrossChainAccountInfo> { try { // Fetch data from both networks in parallel const [vfxInfo, btcInfo] = await Promise.all([ this.vfxClient.getAddressDetails(vfxAddress), this.btcClient.getAddressInfo(btcAddress) ]);
return { vfx: { address: vfxAddress, balance: vfxInfo.balance, domain: vfxInfo.adnr, txCount: vfxInfo.txCount }, bitcoin: { address: btcAddress, balance: btcInfo.balance, balanceBTC: btcInfo.balance / 100000000, txCount: btcInfo.txCount, addressTypes: await this.getBitcoinAddressTypes(btcAddress) } }; } catch (error) { console.error('Error fetching cross-chain account info:', error); throw error; } }
private async getBitcoinAddressTypes(address: string) { // If we have the original keypair, we could show all address types // For now, just return the queried address return { primary: address }; }
async getUnifiedTransactionHistory(vfxAddress: string, btcAddress: string) { try { const [vfxTxs, btcTxs] = await Promise.all([ this.vfxClient.getAddressDetails(vfxAddress), // VFX doesn't have separate tx history endpoint this.btcClient.getTransactions(btcAddress, 10) // Get last 10 Bitcoin transactions ]);
return { vfx: { transactionCount: vfxTxs.txCount, // Note: VFX SDK doesn't currently expose transaction history // This would need to be added to get detailed transaction list }, bitcoin: { transactionCount: btcTxs.length, transactions: btcTxs.map(tx => ({ id: tx.txid, confirmed: tx.status.confirmed, blockHeight: tx.status.block_height, fee: tx.fee, size: tx.size })) } }; } catch (error) { console.error('Error fetching transaction history:', error); throw error; } }}
// Usageasync function showCrossChainDashboard() { const dashboard = new CrossChainDashboard(Network.Testnet, 'testnet');
const accountInfo = await dashboard.getUnifiedAccountInfo( 'vfx-address-here', 'bitcoin-address-here' );
console.log('Cross-Chain Account Dashboard:'); console.log('============================='); console.log('VFX Balance:', accountInfo.vfx.balance, 'VFX'); console.log('VFX Domain:', accountInfo.vfx.domain || 'None'); console.log('VFX Transactions:', accountInfo.vfx.txCount); console.log(''); console.log('Bitcoin Balance:', accountInfo.bitcoin.balanceBTC, 'BTC'); console.log('Bitcoin Balance (sats):', accountInfo.bitcoin.balance); console.log('Bitcoin Transactions:', accountInfo.bitcoin.txCount);}Cross-Chain Transaction Coordinator
Section titled “Cross-Chain Transaction Coordinator”Coordinate transactions across both networks:
class CrossChainTransactionCoordinator { private vfxClient: VfxClient; private btcClient: btc.BtcClient;
constructor(vfxNetwork: Network, btcNetwork: 'mainnet' | 'testnet') { this.vfxClient = new VfxClient(vfxNetwork); this.btcClient = new btc.BtcClient(btcNetwork); }
// Send VFX transaction async sendVfxTransaction(fromKeypair: any, toAddress: string, amount: number) { try { console.log(`Sending ${amount} VFX to ${toAddress}`); const result = await this.vfxClient.sendCoin(fromKeypair, toAddress, amount); console.log('VFX transaction successful:', result.txHash); return { success: true, txHash: result.txHash, network: 'vfx' }; } catch (error) { console.error('VFX transaction failed:', error.message); return { success: false, error: error.message, network: 'vfx' }; } }
// Send Bitcoin transaction async sendBitcoinTransaction(fromWif: string, toAddress: string, amountSats: number, feeRate?: number) { try { console.log(`Sending ${amountSats} satoshis to ${toAddress}`); const txId = await this.btcClient.sendBtc(fromWif, toAddress, amountSats, feeRate); console.log('Bitcoin transaction successful:', txId); return { success: true, txHash: txId, network: 'bitcoin' }; } catch (error) { console.error('Bitcoin transaction failed:', error.message); return { success: false, error: error.message, network: 'bitcoin' }; } }
// Coordinate simultaneous transactions (for atomic swaps or similar) async coordinateTransactions( vfxTx: { fromKeypair: any; toAddress: string; amount: number }, btcTx: { fromWif: string; toAddress: string; amountSats: number; feeRate?: number } ) { try { console.log('Coordinating cross-chain transactions...');
// Execute both transactions in parallel const [vfxResult, btcResult] = await Promise.all([ this.sendVfxTransaction(vfxTx.fromKeypair, vfxTx.toAddress, vfxTx.amount), this.sendBitcoinTransaction(btcTx.fromWif, btcTx.toAddress, btcTx.amountSats, btcTx.feeRate) ]);
return { vfx: vfxResult, bitcoin: btcResult, success: vfxResult.success && btcResult.success }; } catch (error) { console.error('Cross-chain coordination failed:', error.message); return { success: false, error: error.message }; } }
// Monitor transaction confirmations across both networks async monitorTransactions(vfxTxHash?: string, btcTxHash?: string) { const status = { vfx: { confirmed: false, txHash: vfxTxHash }, bitcoin: { confirmed: false, txHash: btcTxHash } };
// Note: This would require additional API endpoints to check transaction status // For now, we'll return the initial status console.log('Transaction monitoring started...'); console.log('VFX TX:', vfxTxHash); console.log('BTC TX:', btcTxHash);
return status; }}
// Usage exampleasync function performCrossChainTransaction() { const coordinator = new CrossChainTransactionCoordinator(Network.Testnet, 'testnet');
// Prepare VFX transaction const vfxKeypair = { private: 'vfx-private-key', public: 'vfx-public-key', address: 'vfx-address' };
// Coordinate transactions const result = await coordinator.coordinateTransactions( { fromKeypair: vfxKeypair, toAddress: 'recipient-vfx-address', amount: 100 }, { fromWif: 'sender-bitcoin-wif', toAddress: 'recipient-bitcoin-address', amountSats: 50000, feeRate: 20 } );
console.log('Cross-chain transaction result:', result);}Domain Name Integration
Section titled “Domain Name Integration”Leverage VFX domains for cross-chain address resolution:
class CrossChainDomainService { private vfxClient: VfxClient; private btcClient: btc.BtcClient;
constructor(vfxNetwork: Network, btcNetwork: 'mainnet' | 'testnet') { this.vfxClient = new VfxClient(vfxNetwork); this.btcClient = new btc.BtcClient(btcNetwork); }
// Register a domain with both VFX and Bitcoin addresses async registerCrossChainDomain( vfxKeypair: any, domain: string, bitcoinAddress: string ) { try { // Check if domain is available const available = await this.vfxClient.domainAvailable(domain); if (!available) { throw new Error(`Domain ${domain} is not available`); }
// Purchase VFX domain const result = await this.vfxClient.buyVfxDomain(vfxKeypair, domain); console.log(`Domain ${domain} registered for VFX address: ${vfxKeypair.address}`);
// Store Bitcoin address association (would require additional service) // For now, we'll just log it console.log(`Bitcoin address ${bitcoinAddress} associated with ${domain}`);
return { success: true, domain, vfxAddress: vfxKeypair.address, bitcoinAddress, transaction: result }; } catch (error) { console.error('Domain registration failed:', error.message); return { success: false, error: error.message }; } }
// Resolve domain to get both addresses async resolveCrossChainDomain(domain: string) { try { // Get VFX address from domain const vfxAddress = await this.vfxClient.lookupDomain(domain);
// Get Bitcoin address (would require additional service/storage) // For demonstration, we'll try the Bitcoin domain lookup let bitcoinAddress; try { bitcoinAddress = await this.vfxClient.lookupBtcDomain(domain); } catch { bitcoinAddress = null; }
return { domain, vfxAddress, bitcoinAddress, resolved: true }; } catch (error) { console.error('Domain resolution failed:', error.message); return { domain, resolved: false, error: error.message }; } }}
// Usageasync function domainExample() { const domainService = new CrossChainDomainService(Network.Testnet, 'testnet');
// Resolve existing domain const resolution = await domainService.resolveCrossChainDomain('example.vfx'); console.log('Domain resolution:', resolution);}Complete Cross-Chain Application Example
Section titled “Complete Cross-Chain Application Example”Here’s a complete example bringing everything together:
import { VfxClient, btc, Network } from 'vfx-web-sdk';
class CrossChainWalletApp { private vfxClient: VfxClient; private btcClient: btc.BtcClient; private wallet: any;
constructor(network: 'mainnet' | 'testnet' = 'testnet') { this.vfxClient = new VfxClient(network === 'mainnet' ? Network.Mainnet : Network.Testnet); this.btcClient = new btc.BtcClient(network); }
// Initialize wallet from credentials async initializeWallet(email: string, password: string, vfxMnemonic?: string) { // Create Bitcoin wallet from email/password const btcWallet = this.btcClient.generateEmailKeypair(email, password, 0);
// Create VFX wallet (from mnemonic if provided, otherwise generate new) let vfxWallet; if (vfxMnemonic) { const vfxPrivateKey = this.vfxClient.privateKeyFromMneumonic(vfxMnemonic, 0); vfxWallet = { mnemonic: vfxMnemonic, private: vfxPrivateKey, public: this.vfxClient.publicFromPrivate(vfxPrivateKey), address: this.vfxClient.addressFromPrivate(vfxPrivateKey) }; } else { const mnemonic = this.vfxClient.generateMnemonic(12); const vfxPrivateKey = this.vfxClient.privateKeyFromMneumonic(mnemonic, 0); vfxWallet = { mnemonic, private: vfxPrivateKey, public: this.vfxClient.publicFromPrivate(vfxPrivateKey), address: this.vfxClient.addressFromPrivate(vfxPrivateKey) }; }
this.wallet = { credentials: { email, password }, vfx: vfxWallet, bitcoin: btcWallet };
return this.wallet; }
// Get complete wallet status async getWalletStatus() { if (!this.wallet) throw new Error('Wallet not initialized');
try { const [vfxInfo, btcInfo] = await Promise.all([ this.vfxClient.getAddressDetails(this.wallet.vfx.address), this.btcClient.getAddressInfo(this.wallet.bitcoin.address) ]);
return { vfx: { address: this.wallet.vfx.address, balance: vfxInfo.balance, domain: vfxInfo.adnr, transactions: vfxInfo.txCount }, bitcoin: { address: this.wallet.bitcoin.address, addresses: this.wallet.bitcoin.addresses, balance: btcInfo.balance, balanceBTC: btcInfo.balance / 100000000, transactions: btcInfo.txCount } }; } catch (error) { console.error('Error fetching wallet status:', error); throw error; } }
// Send VFX async sendVfx(toAddress: string, amount: number) { if (!this.wallet) throw new Error('Wallet not initialized');
return await this.vfxClient.sendCoin( { private: this.wallet.vfx.private, public: this.wallet.vfx.public, address: this.wallet.vfx.address }, toAddress, amount ); }
// Send Bitcoin async sendBitcoin(toAddress: string, amountSats: number, feeRate?: number) { if (!this.wallet) throw new Error('Wallet not initialized');
return await this.btcClient.sendBtc( this.wallet.bitcoin.wif, toAddress, amountSats, feeRate ); }
// Export wallet for backup exportWallet() { if (!this.wallet) throw new Error('Wallet not initialized');
return { email: this.wallet.credentials.email, password: this.wallet.credentials.password, vfxMnemonic: this.wallet.vfx.mnemonic, vfxAddress: this.wallet.vfx.address, bitcoinAddress: this.wallet.bitcoin.address, bitcoinWif: this.wallet.bitcoin.wif }; }}
// Usage demonstrationasync function demonstrateCrossChainApp() { const app = new CrossChainWalletApp('testnet');
// Initialize wallet const wallet = await app.initializeWallet('user@example.com', 'secure-password'); console.log('Wallet initialized:'); console.log('VFX Address:', wallet.vfx.address); console.log('Bitcoin Address:', wallet.bitcoin.address); console.log('VFX Mnemonic:', wallet.vfx.mnemonic);
// Get wallet status try { const status = await app.getWalletStatus(); console.log('\nWallet Status:'); console.log('VFX Balance:', status.vfx.balance, 'VFX'); console.log('Bitcoin Balance:', status.bitcoin.balanceBTC, 'BTC'); } catch (error) { console.log('New wallet - no balance yet'); }
// Export for backup const backup = app.exportWallet(); console.log('\nWallet backup data:', backup);}
demonstrateCrossChainApp().catch(console.error);Best Practices for Cross-Chain Development
Section titled “Best Practices for Cross-Chain Development”Security
Section titled “Security”- Secure credential storage: Protect email/password combinations
- Separate key management: Use different security levels for different amounts
- Multi-signature support: Consider multi-sig for large amounts
User Experience
Section titled “User Experience”- Unified interfaces: Present both networks seamlessly
- Clear network indicators: Always show which network operations affect
- Gas/fee estimation: Show costs for both networks
Architecture
Section titled “Architecture”- Modular design: Separate VFX and Bitcoin logic
- Error isolation: Don’t let one network’s issues affect the other
- Async operations: Handle network delays gracefully
What’s Next?
Section titled “What’s Next?”Now that you understand cross-chain integration:
- Build Advanced Apps: Explore Complete Applications
- See More Examples: Check out Code Snippets
- API Deep Dive: Study the API References
Cross-chain development opens up exciting possibilities. Start building the future of decentralized finance!