@arklabs/wallet-sdk
Version:
Bitcoin wallet SDK with Taproot and Ark integration
74 lines (73 loc) • 2.58 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.selectCoins = selectCoins;
exports.selectVirtualCoins = selectVirtualCoins;
/**
* Select coins to reach a target amount, prioritizing those closer to expiry
* @param coins List of coins to select from
* @param targetAmount Target amount to reach in satoshis
* @returns Selected coins and change amount, or null if insufficient funds
*/
function selectCoins(coins, targetAmount) {
// Sort coins by amount (descending)
const sortedCoins = [...coins].sort((a, b) => b.value - a.value);
const selectedCoins = [];
let selectedAmount = 0;
// Select coins until we have enough
for (const coin of sortedCoins) {
selectedCoins.push(coin);
selectedAmount += coin.value;
if (selectedAmount >= targetAmount) {
break;
}
}
// Check if we have enough
if (selectedAmount < targetAmount) {
return { inputs: null, changeAmount: 0 };
}
// Calculate change
const changeAmount = selectedAmount - targetAmount;
return {
inputs: selectedCoins,
changeAmount,
};
}
/**
* Select virtual coins to reach a target amount, prioritizing those closer to expiry
* @param coins List of virtual coins to select from
* @param targetAmount Target amount to reach in satoshis
* @returns Selected coins and change amount, or null if insufficient funds
*/
function selectVirtualCoins(coins, targetAmount) {
// Sort VTXOs by expiry (ascending) and amount (descending)
const sortedCoins = [...coins].sort((a, b) => {
// First sort by expiry if available
const expiryA = a.virtualStatus.batchExpiry || Number.MAX_SAFE_INTEGER;
const expiryB = b.virtualStatus.batchExpiry || Number.MAX_SAFE_INTEGER;
if (expiryA !== expiryB) {
return expiryA - expiryB; // Earlier expiry first
}
// Then sort by amount
return b.value - a.value; // Larger amount first
});
const selectedCoins = [];
let selectedAmount = 0;
// Select coins until we have enough
for (const coin of sortedCoins) {
selectedCoins.push(coin);
selectedAmount += coin.value;
if (selectedAmount >= targetAmount) {
break;
}
}
// Check if we have enough
if (selectedAmount < targetAmount) {
return { inputs: null, changeAmount: 0 };
}
// Calculate change
const changeAmount = selectedAmount - targetAmount;
return {
inputs: selectedCoins,
changeAmount,
};
}