@hlvuser/ability-hedera-htlc
v1.0.0
Published
Vincent ability to create HTLCs on Hedera for HLV Protocol
Readme
Hedera HTLC Creation Ability
Vincent ability to create Hash Time-Locked Contracts (HTLCs) on Hedera for HLV Protocol.
Purpose
This ability locks wBTC on Hedera with a payment hash from a Lightning invoice:
- Lightning invoice created → generates payment hash
- This ability locks wBTC in HTLC with that payment hash
- Agent pays Lightning invoice → receives preimage
- Agent claims wBTC by submitting preimage to HTLC
- Atomic guarantee: Either both chains settle or both refund
Flow
Create LN Invoice → Get Payment Hash → Lock wBTC in HTLC → Pay Invoice → Get Preimage → Claim wBTCHedera Network Configuration
Supported Networks
| Network | Chain ID | RPC URL | | ---------- | -------- | ----------------------------- | | Mainnet | 295 | https://mainnet.hedera.com | | Testnet | 296 | https://testnet.hedera.com | | Previewnet | 297 | https://previewnet.hedera.com |
Currently deployed on Hedera Testnet (chainId: 296)
Ability Parameters
{
paymentHash: string; // From Lightning invoice (bytes32)
amount: string; // wBTC amount in wei
tokenAddress: string; // wBTC contract address
htlcContractAddress: string; // HTLC contract address
timelock: number; // Unix timestamp for refund
rpcUrl: string; // Hedera RPC URL
chainId: number; // 296 for testnet
}Response
{
contractId: string; // HTLC contract ID (keccak256)
txHash: string; // Transaction hash
paymentHash: string; // Payment hash (for reference)
amount: string; // Amount locked
timelock: number; // Timelock timestamp
}Usage Example
import { getVincentAbilityClient } from '@lit-protocol/vincent-app-sdk/abilityClient';
import { bundledVincentAbility } from '@hlv/ability-hedera-htlc';
const abilityClient = getVincentAbilityClient({
bundledVincentAbility,
ethersSigner: yourEthersSigner,
});
// First, user must approve wBTC spending (one-time)
// This can be done via another ability or manually
// Precheck
const precheckResult = await abilityClient.precheck(
{
paymentHash: '0x1234...', // From Lightning invoice
amount: '1000000000000000000', // 1 wBTC in wei
tokenAddress: '0x...', // wBTC on Hedera
htlcContractAddress: '0x...', // Deployed HTLC
timelock: Math.floor(Date.now() / 1000) + 86400, // 24h
rpcUrl: 'https://testnet.hedera.com',
chainId: 296,
},
{
delegatorPkpEthAddress: userVincentWalletAddress,
},
);
if (!precheckResult.success) {
console.error('Precheck failed:', precheckResult.result.error);
// May need to approve token spending first
}
// Execute
const result = await abilityClient.execute(
{
/* same params */
},
{ delegatorPkpEthAddress: userVincentWalletAddress },
);
if (result.success) {
const { contractId, txHash } = result.result;
// HTLC created! Now monitor for Lightning payment
}Complete Rebalance Flow
1. Calculate Rebalance Amount
// Get user's wBTC balance
const wbtcBalance = await getWBTCBalance(userAddress);
// Calculate 20% for rebalancing (as requested)
const rebalanceAmount = wbtcBalance.mul(20).div(100);
// Convert to satoshis for Lightning
const sats = convertWBTCToSats(rebalanceAmount);2. Create Lightning Invoice
const invoiceResult = await lightningInvoiceAbility.execute({
amountSat: sats,
description: 'HLV Rebalance',
nwcUri: userNWCUri,
});
const { paymentHash, paymentRequest } = invoiceResult.result;3. Create HTLC
const htlcResult = await hederaHTLCAbility.execute({
paymentHash,
amount: rebalanceAmount.toString(),
tokenAddress: WBTC_ADDRESS,
htlcContractAddress: HTLC_CONTRACT_ADDRESS,
timelock: Math.floor(Date.now() / 1000) + 86400,
rpcUrl: 'https://testnet.hedera.com',
chainId: 296,
});
const { contractId } = htlcResult.result;4. Monitor and Claim (Backend Job)
// Agent monitors Lightning payment
// When payment succeeds, agent gets preimage
// Agent submits preimage to claim wBTC
await htlcContract.claim(contractId, preimage);HTLC Contract Interface
The ability interacts with this Solidity interface:
function createHTLCToken(
bytes32 _hashlock, // Payment hash from Lightning
uint256 _timelock, // Unix timestamp for refund
address _tokenAddress, // wBTC address
uint256 _amount // Amount to lock
) external returns (bytes32 contractId);
function claim(
bytes32 _contractId,
bytes32 _preimage // Revealed after Lightning payment
) external;
function refund(
bytes32 _contractId // After timelock expires
) external;Token Approval
Before creating HTLCs, users must approve wBTC spending:
// Option 1: Separate approval transaction
await wbtcContract.approve(htlcContractAddress, amount);
// Option 2: Use ERC20 Approval ability (recommended)
await erc20ApprovalAbility.execute({
tokenAddress: WBTC_ADDRESS,
spender: HTLC_CONTRACT_ADDRESS,
amount: amount.toString(),
});Security Considerations
Timelock Safety
- Minimum: 1 hour (3600 seconds)
- Recommended: 24 hours (86400 seconds)
- Maximum: No limit, but longer = more capital locked
Payment Hash Verification
The HTLC contract verifies:
require(
hashlock == sha256(abi.encodePacked(preimage)),
"Invalid preimage"
);Refund Protection
- If Lightning payment fails → User can refund after timelock
- If agent doesn't claim → User gets tokens back
- Atomic guarantee: No loss of funds
Integration with hlv-starter-app
Backend Integration
// In hlv-backend job worker
import { executeRebalance } from './jobs/rebalanceJob';
async function rebalanceJob(userId: string, wbtcAmount: string) {
// 1. Create Lightning invoice
const invoice = await createLightningInvoice({
amountSat: convertToSats(wbtcAmount),
});
// 2. Create HTLC with payment hash
const htlc = await createHederaHTLC({
paymentHash: invoice.paymentHash,
amount: wbtcAmount,
});
// 3. Save to database
await Swap.create({
invoiceRequest: invoice.paymentRequest,
htlcContractId: htlc.contractId,
status: 'pending',
});
}Frontend Integration
// In hlv-frontend
const handleRebalance = async () => {
// Show rebalance dialog
const confirmed = await showRebalanceDialog({
amount: wbtcBalance * 0.2, // 20%
estimatedSats: calculateSats(wbtcBalance * 0.2),
});
if (confirmed) {
// Trigger backend job
await api.post('/api/rebalance', {
userAddress,
wbtcAmount: wbtcBalance * 0.2,
});
// Show monitoring UI
navigate('/swaps/active');
}
};Environment Variables
# HTLC Contract (from deployment)
HTLC_CONTRACT_ADDRESS=0x...
# wBTC Token
WBTC_TOKEN_ADDRESS=0x...
# Hedera Network
HEDERA_RPC_URL=https://testnet.hedera.com
HEDERA_CHAIN_ID=296
# For testing
TEST_PAYMENT_HASH=0x1234...
TEST_AMOUNT=1000000000000000000Development
# Install dependencies
pnpm install
# Build
pnpm build
# Test
pnpm test
# Deploy to IPFS
pnpm deployRelated Abilities
- @hlv/ability-lightning-invoice: Creates invoices (returns payment hash)
- @lit-protocol/vincent-ability-evm-transaction-signer: Signs Hedera transactions
- @lit-protocol/vincent-ability-erc20-approval: Approves token spending
TODO
- [ ] Add EIP-1559 gas pricing support
- [ ] Implement batch HTLC creation
- [ ] Add HTLC monitoring utilities
- [ ] Support native HBAR HTLCs
- [ ] Add claim and refund functions
- [ ] Integrate with Hedera SDK for better gas estimation
- [ ] Add comprehensive test suite
License
MIT
