Skip to content

Commit

Permalink
patch: use multiple collateral inputs
Browse files Browse the repository at this point in the history
  • Loading branch information
micahkendall committed Sep 2, 2024
1 parent 5728e34 commit 97ca100
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 13 deletions.
5 changes: 5 additions & 0 deletions .changeset/hot-brooms-camp.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@blaze-cardano/tx": patch
---

patch: use multiple collateral inputs
57 changes: 44 additions & 13 deletions packages/blaze-tx/src/tx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1084,7 +1084,7 @@ export class TxBuilder {
const inputs = [...this.body.inputs().values()];
const scope = [...this.utxoScope.values()];
// Initialize variables to track the best UTXO for collateral and its ranking.
let [best, rank]: [TransactionUnspentOutput | undefined, number] = [
let [best, rank]: [TransactionUnspentOutput[] | undefined, number] = [
undefined,
99,
];
Expand All @@ -1094,15 +1094,15 @@ export class TxBuilder {
if (utxo) {
// Check if the UTXO amount is sufficient for collateral.
if (
utxo.output().amount().coin() >= 10n * 10n ** 6n &&
utxo.output().amount().coin() >= 5_000_000 &&
utxo.output().address().getProps().paymentPart?.type ==
CredentialType.KeyHash
) {
const ranking = value.assetTypes(utxo.output().amount());
// Update the best UTXO and its ranking if it's a better candidate.
if (ranking < rank) {
rank = ranking;
best = utxo;
best = [utxo];
}
}
} else {
Expand All @@ -1119,29 +1119,60 @@ export class TxBuilder {
const ranking = value.assetTypes(utxo.output().amount());
if (ranking < rank) {
rank = ranking;
best = utxo;
best = [utxo];
}
}
}
if (best) {
this.utxoScope.add(best);
for (const bestUtxo of best) {
this.utxoScope.add(bestUtxo);
}
} else {
throw new Error("prepareCollateral: could not find enough collateral");
let adaAmount = 0n;
// create a sorted list of utxos by ada amount
const adaUtxos = [...this.utxos.values()].sort((a, b) =>
a.output().amount().coin() < b.output().amount().coin() ? -1 : 1,
);
for (
let i = 0;
i < Math.min(this.params.maxCollateralInputs, adaUtxos.length);
i++
) {
adaAmount += adaUtxos[i]!.output().amount().coin();
if (adaAmount >= 5_000_000n) {
break;
}
}
if (adaAmount <= 5_000_000) {
throw new Error(
"prepareCollateral: could not find enough collateral (5 ada minimum)",
);
}
best = adaUtxos;
}
}
// Set the selected UTXO as collateral in the transaction body.
const tis = CborSet.fromCore([], TransactionInput.fromCore);
tis.setValues([best.input()]);
tis.setValues(best.map((x) => x.input()));
this.body.setCollateral(tis);

const key = best.output().address().getProps().paymentPart!;
if (key.type == CredentialType.ScriptHash) {
this.requiredNativeScripts.add(key.hash);
} else {
this.requiredWitnesses.add(HashAsPubKeyHex(key.hash));
for (const bestUtxo of best) {
const key = bestUtxo.output().address().getProps().paymentPart!;
if (key.type == CredentialType.ScriptHash) {
this.requiredNativeScripts.add(key.hash);
} else {
this.requiredWitnesses.add(HashAsPubKeyHex(key.hash));
}
}
// Also set the collateral return to the output of the selected UTXO.
this.body.setCollateralReturn(best.output());
const ret = new TransactionOutput(
this.changeAddress!,
best.reduce(
(acc, x) => value.merge(acc, x.output().amount()),
value.zero(),
),
);
this.body.setCollateralReturn(ret);
}

/**
Expand Down

0 comments on commit 97ca100

Please sign in to comment.