Skip to content

Instantly share code, notes, and snippets.

@mahsumurebe
Last active February 16, 2023 08:44
Show Gist options
  • Save mahsumurebe/e469476f19290c3a2bdb606a75c84325 to your computer and use it in GitHub Desktop.
Save mahsumurebe/e469476f19290c3a2bdb606a75c84325 to your computer and use it in GitHub Desktop.
Select Unspend Transaction Output
import Big from 'big.js';
interface listunspent {
txid: string,
vout: number,
address: string,
amount: number,
confirmations: number,
spendable: boolean,
}
let unspentTransactions: listunspent[] = [
{
txid: '1ffffff12312afdfa31',
vout: 1,
address: 'abc1',
amount: 0.1,
confirmations: 10,
spendable: true,
},
{
txid: '2fffffffbacefd1231',
vout: 2,
address: 'abc1',
amount: 0.5,
confirmations: 10,
spendable: true,
},
{
txid: '3ffffffff19afd9123',
vout: 3,
address: 'abc1',
amount: 0.7,
confirmations: 10,
spendable: true,
},
{
txid: '4fffffffbafe91239',
vout: 4,
address: 'abc1',
amount: 1.2,
confirmations: 10,
spendable: true,
},
]
.filter(a => a.spendable)
.sort((a, b) => a.amount - b.amount);
const decimal = 8;
function pick(amount: Big): listunspent[] {
let inputs = [];
let filteredOutputs = [];
filteredOutputs = unspentTransactions
.filter(a => new Big(a.amount).eq(amount));
// If the amount to be sent is not included in the unspent transaction output
if (filteredOutputs.length === 0) {
// Sort unspent outputs by balance ascending
filteredOutputs = unspentTransactions
.filter(a => amount.gt(a.amount));
let total: Big = new Big(0);
for (const filter of filteredOutputs) {
total = total.plus(filter.amount);
inputs.push(filter);
if (total >= amount) {
let diff = total.minus(amount);
if (diff.gt(0)) {
let removeList = filteredOutputs.filter(a => diff.gte(a.amount))
.sort((a, b) => b.amount - a.amount);
let total2 = total;
for (const r of removeList) {
total2 = total2.minus(r.amount);
if (total2 >= amount) {
const index = inputs.findIndex(a => a.txid === r.txid);
if (index > -1) {
delete inputs[index];
}
}
}
}
break;
}
}
if (total < amount) {
inputs = [];
for (const filter of unspentTransactions) {
if (amount.lt(filter.amount)) {
inputs.push(filter);
break;
}
}
if (inputs.length === 0) {
throw new Error('Insufficient funds.');
}
}
} else {
inputs = filteredOutputs;
}
return inputs.filter(el => !!el);
}
console.log(pick(new Big(0.5)).map(tx => tx.txid).join(', ')); // 2fffffffbacefd1231
console.log(pick(new Big(0.6)).map(tx => tx.txid).join(', ')); // 1ffffff12312afdfa31, 2fffffffbacefd1231
console.log(pick(new Big(0.65)).map(tx => tx.txid).join(', ')); // 3ffffffff19afd9123
console.log(pick(new Big(0.8)).map(tx => tx.txid).join(', ')); // 1ffffff12312afdfa31, 3ffffffff19afd9123
console.log(pick(new Big(2.5)).map(tx => tx.txid).join(', ')); // 1ffffff12312afdfa31, 2fffffffbacefd1231, 3ffffffff19afd9123, 4fffffffbafe91239
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment