@trezor/connect
Version:
High-level javascript interface for Trezor hardware wallet.
139 lines • 4.84 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TransactionComposer = void 0;
const bigNumber_1 = require("@trezor/utils/lib/bigNumber");
const utxo_lib_1 = require("@trezor/utxo-lib");
const fees_1 = require("../../backend/fees");
class TransactionComposer {
account;
utxos;
outputs;
coinInfo;
blockHeight = 0;
baseFee;
sortingStrategy;
feeLevels;
composed = {};
constructor(options) {
this.account = options.account;
this.outputs = options.outputs;
this.coinInfo = options.coinInfo;
this.blockHeight = 0;
this.baseFee = options.baseFee || 0;
this.sortingStrategy = options.sortingStrategy;
this.feeLevels = (0, fees_1.getOrInitBitcoinFeeLevels)(options.coinInfo);
const { addresses } = options.account;
const allAddresses = !addresses
? []
: addresses.used
.concat(addresses.unused)
.concat(addresses.change)
.map(a => a.address);
this.utxos = options.utxos.flatMap(u => {
if (!u.required && new bigNumber_1.BigNumber(u.amount).lte(this.coinInfo.dustLimit))
return [];
return {
...u,
coinbase: typeof u.coinbase === 'boolean' ? u.coinbase : false,
own: allAddresses.indexOf(u.address) >= 0,
};
});
}
async init(blockchain) {
const { blockHeight } = await blockchain.getNetworkInfo();
this.blockHeight = blockHeight;
if (!this.feeLevels.wasFetchedSuccessfully) {
await this.feeLevels.load(blockchain);
}
}
composeAllFeeLevels() {
const { levels } = this.feeLevels;
if (this.utxos.length < 1)
return false;
this.composed = {};
let atLeastOneValid = false;
levels.forEach(level => {
if (level.feePerUnit !== '0') {
const tx = this.compose(level.feePerUnit);
if (tx.type === 'final') {
atLeastOneValid = true;
}
this.composed[level.label] = tx;
}
});
if (!atLeastOneValid) {
const lastLevel = levels[levels.length - 1];
let lastFee = new bigNumber_1.BigNumber(lastLevel.feePerUnit);
while (lastFee.gt(this.coinInfo.minFee) && this.composed.custom === undefined) {
lastFee = lastFee.minus(1);
const tx = this.compose(lastFee.toString());
if (tx.type === 'final') {
this.feeLevels.updateBitcoinCustomFee(lastFee.toString());
this.composed.custom = tx;
return true;
}
}
return false;
}
return true;
}
composeCustomFee(fee) {
const tx = this.compose(fee);
this.composed.custom = tx;
if (tx.type === 'final') {
this.feeLevels.updateBitcoinCustomFee(tx.feePerByte);
}
else {
this.feeLevels.updateBitcoinCustomFee(fee);
}
}
getFeeLevelList() {
const list = [];
const { levels } = this.feeLevels;
levels.forEach(level => {
const tx = this.composed[level.label];
if (tx && tx.type === 'final') {
list.push({
name: level.label,
fee: tx.fee,
feePerByte: level.feePerUnit,
blocks: level.blocks,
minutes: level.blocks * this.coinInfo.blockTime,
total: tx.totalSpent,
});
}
else {
list.push({
name: level.label,
fee: '0',
disabled: true,
});
}
});
return list;
}
compose(feeRate) {
const { account, coinInfo, baseFee } = this;
const { addresses } = account;
if (!addresses)
return { type: 'error', error: 'ADDRESSES-NOT-SET' };
const changeAddress = addresses.change.find(a => !a.transfers) ||
addresses.change[addresses.change.length - 1];
return (0, utxo_lib_1.composeTx)({
txType: account.type,
utxos: this.utxos,
outputs: this.outputs,
feeRate,
longTermFeeRate: this.feeLevels.longTermFeeRate,
sortingStrategy: this.sortingStrategy,
network: coinInfo.network,
changeAddress,
dustThreshold: coinInfo.dustLimit,
baseFee,
});
}
dispose() {
}
}
exports.TransactionComposer = TransactionComposer;
//# sourceMappingURL=TransactionComposer.js.map