Arkade provides seamless integration with the Lightning Network through Boltz submarine swaps, allowing users to move funds between Arkade and Lightning channels. This integration leverages Hash Time-Locked Contracts (HTLCs) to ensure trustless and secure cross-chain atomic swaps.
Overview
The BoltzSwapProvider
library extends Arkade’s functionality by enabling:
- Lightning to Arkade swaps - Receive funds from Lightning payments into your Arkade wallet
- Arkade to Lightning swaps - Send funds from your Arkade wallet to Lightning invoices
This integration is built on top of the Boltz submarine swap protocol, providing a reliable and secure way to bridge the gap between Arkade and the Lightning Network.
Installation
npm install @arkade-os/sdk @arkade-os/boltz-swap
Basic Usage
Initializing the Lightning Swap Provider
import { Wallet } from '@arkade-os/wallet-sdk';
import { ArkadeLightning, BoltzSwapProvider } from '@arkade-os/boltz-swap';
// Initialize your Arkade wallet
const wallet = await Wallet.create({
identity,
arkServerUrl: 'https://mutinynet.arkade.sh',
});
// Initialize the Lightning swap provider
const swapProvider = new BoltzSwapProvider({
apiUrl: 'https://api.boltz.exchange',
network: 'mainnet'
});
// Create the ArkadeLightning instance
const arkadeLightning = new ArkadeLightning({
wallet,
swapProvider
});
Receiving Lightning Payments
To receive a Lightning payment into your Arkade wallet:
// Create a Lightning invoice that will deposit funds to your Arkade wallet
const result = await arkadeLightning.createLightningInvoice({
amountSats: 50000, // 50,000 sats
description: 'Payment to my Arkade wallet'
});
console.log('Lightning Invoice:', result.invoice);
console.log('Payment Hash:', result.paymentHash);
console.log('Expiry (seconds):', result.expirySeconds);
// The invoice can now be shared with the payer
// When paid, funds will appear in your Arkade wallet
Monitoring Incoming Lightning Payments
You can monitor the status of incoming Lightning payments:
// Monitor the payment by payment hash
const subscription = arkadeLightning.monitorIncomingPayment(result.paymentHash);
subscription.on('pending', () => {
console.log('Payment detected but not yet confirmed');
});
subscription.on('confirmed', (txDetails) => {
console.log('Payment confirmed!');
console.log('Transaction ID:', txDetails.txid);
console.log('Amount received:', txDetails.amountSats, 'sats');
// Update your UI or notify the user
updateBalanceDisplay();
});
subscription.on('failed', (error) => {
console.error('Payment failed:', error.message);
});
// Don't forget to clean up when done
subscription.unsubscribe();
Sending Lightning Payments
To send a payment from your Arkade wallet to a Lightning invoice:
// Parse a Lightning invoice
const invoiceDetails = await arkadeLightning.decodeInvoice(
'lnbc500u1pj...' // Lightning invoice string
);
console.log('Invoice amount:', invoiceDetails.amountSats, 'sats');
console.log('Description:', invoiceDetails.description);
console.log('Destination:', invoiceDetails.destination);
// Pay the Lightning invoice from your Arkade wallet
try {
const paymentResult = await arkadeLightning.sendLightningPayment({
invoice: 'lnbc500u1pj...', // Lightning invoice string
// Optional: Specify which VTXOs to use
sourceVtxos: await wallet.getVtxos(),
// Optional: Maximum fee you're willing to pay (in sats)
maxFeeSats: 1000
});
console.log('Payment successful!');
console.log('Preimage:', paymentResult.preimage);
console.log('Transaction ID:', paymentResult.txid);
} catch (error) {
console.error('Payment failed:', error.message);
}
Handling Refunds
In case a Lightning payment fails after the swap has been initiated, the library provides a refund mechanism:
// Set up a refund handler when initializing
const arkadeLightning = new ArkadeLightning({
wallet,
swapProvider,
refundHandler: {
onRefundNeeded: async (swapData) => {
console.log('Initiating refund for swap:', swapData.id);
// You can implement custom logic here, such as:
// - Notifying the user
// - Automatically claiming the refund
// - Logging the event
// Claim the refund automatically
return await arkadeLightning.claimRefund(swapData);
}
}
});
// Or handle refunds manually
const pendingSwaps = await arkadeLightning.getPendingSwaps();
for (const swap of pendingSwaps) {
if (swap.status === 'refundable') {
const refundResult = await arkadeLightning.claimRefund(swap);
console.log('Refund claimed:', refundResult.txid);
}
}
Advanced Configuration
The library supports advanced configuration options for more specific use cases:
const arkadeLightning = new ArkadeLightning({
wallet,
swapProvider,
// Configure timeouts
timeoutConfig: {
swapExpiryBlocks: 144, // Number of blocks until swap expires
invoiceExpirySeconds: 3600, // Invoice expiry in seconds
claimDelayBlocks: 10 // Blocks to wait before claiming
},
// Configure fee limits
feeConfig: {
maxMinerFeeSats: 5000, // Maximum miner fee in sats
maxSwapFeeSats: 1000, // Maximum swap fee in sats
},
// Configure retry logic
retryConfig: {
maxAttempts: 3,
delayMs: 1000
}
});
Error Handling
The library provides detailed error types to help you handle different failure scenarios:
import {
SwapError,
InvoiceExpiredError,
InsufficientFundsError,
NetworkError
} from '@arkade-os/lightning-swap';
try {
await arkadeLightning.sendLightningPayment({
invoice: 'lnbc500u1pj...'
});
} catch (error) {
if (error instanceof InvoiceExpiredError) {
console.error('The invoice has expired. Please request a new one.');
} else if (error instanceof InsufficientFundsError) {
console.error('Not enough funds available:', error.message);
} else if (error instanceof NetworkError) {
console.error('Network issue. Please try again later:', error.message);
} else if (error instanceof SwapError) {
console.error('Swap failed:', error.message);
// You might be able to claim a refund
if (error.isRefundable) {
const refundResult = await arkadeLightning.claimRefund(error.swapData);
console.log('Refund claimed:', refundResult.txid);
}
} else {
console.error('Unknown error:', error);
}
}
Security Considerations
When working with Lightning swaps, keep these security considerations in mind:
-
Timeouts: Always ensure that your HTLCs have appropriate timeouts to prevent funds from being locked indefinitely.
-
Fee Management: Set reasonable fee limits to prevent excessive fees during network congestion.
-
Refund Monitoring: Implement proper monitoring for failed swaps to ensure refunds are claimed promptly.
-
Invoice Validation: Always validate Lightning invoices before initiating payments.
-
Backup Management: Keep proper backups of swap data to be able to claim refunds if needed.
Responses are generated using AI and may contain mistakes.