The other day we had an in-person meeting with @slezica, @yemel, @esneider et al., and we talked about the library architecture. This is what came out of it:
We decided early on that Bitforge should provide accurate representations of protocol objects. These are Transactions, Inputs, Outputs, Addresses, etc. They are immutable and syntactically valid since creation. We cannot check network consensus rules like double spends (for obvious reasons) and script semantics, like valid signatures (which would require us to execute the script, a computationally expensive operation) but, other than that, these objects can be considered well formed and valid.
Bitforge therefore needs a way to model some objects that are in the process of becoming proper protocol objects. The most obvious case of these are unsigned transactions. These objects can (and will) have friendlier interfaces. While the Transaction constructor receives signed inputs and an output list, the object that represents an unsigned transaction TransactionDraft, can handle fees, change, utxos, etc.
We also decided to move the signing logic away from either of these objects, and instead create signing strategies loosely based on BitcoinJ, that are decoupled from each type of input.