UNPKG

@nervosnetwork/ckb-sdk-utils

Version:

Utils module of @nervosnetwork/ckb-sdk-core

45 lines 2.51 kB
import JSBI from 'jsbi'; import calculateTransactionFee from '../calculateTransactionFee.js'; import { getTransactionSize } from '../sizes.js'; import { ReconciliationException } from '../exceptions/index.js'; export const extraInputs = (params) => { const changeThreshold = JSBI.BigInt(`${params.changeThreshold}`); const feeRate = JSBI.BigInt(`${params.feeRate}`); const currentChangeOutput = params.tx.outputs[params.tx.outputs.length - 1]; const currentChange = JSBI.BigInt(currentChangeOutput.capacity); const fee = JSBI.BigInt(calculateTransactionFee(`0x${getTransactionSize(params.tx).toString(16)}`, `0x${feeRate.toString(16)}`)); const lack = JSBI.subtract(JSBI.add(fee, changeThreshold), currentChange); if (JSBI.LE(lack, JSBI.BigInt(0))) { return Object.assign(Object.assign({}, params.tx), { outputs: [ ...params.tx.outputs.slice(0, -1), Object.assign(Object.assign({}, currentChangeOutput), { capacity: `0x${JSBI.subtract(currentChange, fee).toString(16)}` }), ] }); } params.cells.sort((c1, c2) => +JSBI.subtract(JSBI.BigInt(c1.capacity), JSBI.BigInt(c2.capacity))); const SIZE_PER_INPUT = JSBI.BigInt(44); const FEE_PER_INPUT = JSBI.divide(JSBI.multiply(SIZE_PER_INPUT, feeRate), JSBI.BigInt(1000)); for (let i = 1; i <= Math.min(params.extraCount, params.cells.length); i++) { const extraCost = JSBI.multiply(JSBI.BigInt(i), FEE_PER_INPUT); const totalLack = JSBI.add(lack, extraCost); const extraCapacity = params.cells .slice(0, i) .reduce((sum, c) => JSBI.add(sum, JSBI.BigInt(c.capacity)), JSBI.BigInt(0)); if (JSBI.GE(extraCapacity, totalLack)) { const inputs = [ ...params.tx.inputs, ...params.cells.slice(0, i).map(c => ({ previousOutput: c.outPoint, since: '0x0', })), ]; const change = JSBI.add(changeThreshold, JSBI.subtract(extraCapacity, totalLack)); const changeOutput = Object.assign(Object.assign({}, currentChangeOutput), { capacity: `0x${change.toString(16)}` }); const outputs = [...params.tx.outputs.slice(0, -1), changeOutput]; const tx = Object.assign(Object.assign({}, params.tx), { inputs, outputs }); return tx; } } throw new ReconciliationException(); }; export default extraInputs; //# sourceMappingURL=extraInputs.js.map