You have to just append the reveal operation to the contents of the (batched) operation you'd like to inject.
Here is a code snipped extracted from some TS code we wrote:
let header = await getInjectionHeader(tk, injectionBranchOffset);
level = header.level;
let source = await tk.signer.publicKeyHash();
let contract = await tk.rpc.getContract(source);
let counter = parseInt(contract.counter || '0', 10)
let contents: Array<RPCOperation> = []; // This will contain the contents of the TX
let revealEstimate = await tk.estimate.reveal();
if (revealEstimate !== undefined) { // Pk revelation needed. Put it at the beginning
let publicKey = await tk.signer.publicKey();
let revealParams = {
fee: revealEstimate.suggestedFeeMutez,
gasLimit: revealEstimate.gasLimit,
storageLimit: revealEstimate.storageLimit
};
let rpcRevealOperation = await createRevealOperation(revealParams, source, publicKey);
counter++;
contents.push(({ ...rpcRevealOperation, source, counter: counter } as RPCOperation))
}
let len = transfersParams.length;
// process all TXs (enforce sequentiality and ordering with an aux function)
let processTX = async function (i: number): Promise<void> {
if (i >= len) return;
let transferParams = transfersParams[i];
let estimate = await tk.estimate.transfer(transferParams);
const rpcTransferOperation = await createTransferOperation({
...transferParams,
fee: estimate.suggestedFeeMutez,
gasLimit: estimate.gasLimit,
storageLimit: estimate.storageLimit
});
counter++;
let v = {
...rpcTransferOperation,
source,
parameter: transferParams.parameter,
counter: counter,
};
contents.push(v);
await processTX(i + 1);
}
await processTX(0);
let op = objToString({
branch: header.hash,
contents: contents
})
let forgedOp = await tk.rpc.forgeOperations(op)
let signOp = await tk.signer.sign(forgedOp, new Uint8Array([3]));
Hope this helps.