Create a transaction from a wallet coins (UTXOs) with the bcoin library
createTX() doesn't sign the transaction. That is performed by sign() in wallet.js. If your private keys are offline anyway, what kind of unexpected behavior are you getting from createTX()? It wouldn't be able to sign without the keys...?

New functionality was also recently merged to return the MTX before the input scripts are templated (when the public keys are serialized and added to the witness): https://github.com/bcoin-org/bcoin/pull/557 I'm not sure if this helps out your use-case though.

You also might be interested in our own multisig wallet, bmultisig: https://github.com/bcoin-org/bmultisig

This application "plugs in" to the standard bcoin wallet (and full node) and offers hardware support like signing transactions from a Ledger device. Each counterparty of course can sign with their own hardware device at their own convenience.