You can use truffle-hdwallet-provider on top of your HttpProvider. HDWallet Providers will then sign the transaction before broadcasting it out to the provider. It is just a simple wrapper on top of a Provider. Below is my index.js for getting any contract.
let HDWalletProvider = require('truffle-hdwallet-provider')
, Web3 = require('web3')
, path = require('path');
let settings = require('../settings');
function getWeb3Provider() {
return new HDWalletProvider(settings.mnemonic, 'https://network.infura.io/apikey');
}
async function getContract(abi) {
let provider = getWeb3Provider();
let web3 = new Web3(provider);
let artifact = require(path.join(settings.artifactsDir, abi));
let contract = new web3.eth.Contract(artifact.abi, artifact.networks[settings.networkId].address);
contract.setProvider(provider);
return contract
}
module.exports = {
getContract
};
You can then use your functions as is, they'll all be signed by the first private key generated by the mnemonic phase before broadcasting out. If you do not have the mnemonic phase, it is trivial to fork truffle-hdwallet-provider (it is a 60 line module) and have it take a private key instead of a mnemonic phase.