docs: private static void settleCLTVPaymentChannel(String txHash, String output, Coin feePerVkb, boolean allowUnconfirmed) {
          try {
              OutputSpec outputSpec;
              Coin value;
              try {
                  outputSpec = new OutputSpec(output);
                  value = outputSpec.value;
              } catch (AddressFormatException.WrongNetwork e) {
                  System.err.println("Malformed output specification, address is for a different network.");
                  return;
              } catch (AddressFormatException e) {
                  System.err.println("Malformed output specification, could not parse as address.");
                  return;
              } catch (NumberFormatException e) {
                  System.err.println("Malformed output specification, could not parse as value.");
                  return;
              } catch (IllegalArgumentException e) {
                  System.err.println(e.getMessage());
                  return;
              }
  
              SendRequest req = outputSpec.isAddress() ?
                      SendRequest.to(outputSpec.addr, value) :
                      SendRequest.to(params, outputSpec.key, value);
              if (feePerVkb != null)
                  req.setFeePerVkb(feePerVkb);
  
              Transaction lockTimeVerify = wallet.getTransaction(Sha256Hash.wrap(txHash));
              if (lockTimeVerify == null) {
                  System.err.println("Couldn't find transaction with given hash");
                  return;
              }
              TransactionOutput lockTimeVerifyOutput = null;
              for (TransactionOutput out : lockTimeVerify.getOutputs()) {
                  if (ScriptPattern.isSentToCltvPaymentChannel(out.getScriptPubKey())) {
                      lockTimeVerifyOutput = out;
                  }
              }
              if (lockTimeVerifyOutput == null) {
                  System.err.println("TX to spend wasn't sent to LockTimeVerify");
                  return;
              }
  
              if (!value.equals(lockTimeVerifyOutput.getValue())) {
                  System.err.println("You must spend all the money in the input transaction");
              }
  
              if (allowUnconfirmed) {
                  wallet.allowSpendingUnconfirmedTransactions();
              }
              if (password != null) {
                  req.aesKey = passwordToKey(true);
                  if (req.aesKey == null)
                      return;  // Error message already printed.
              }
  
              ECKey key1 = wallet.findKeyFromPubKey(
                      ScriptPattern.extractSenderPubKeyFromCltvPaymentChannel(lockTimeVerifyOutput.getScriptPubKey()));
              ECKey key2 = wallet.findKeyFromPubKey(
                      ScriptPattern.extractRecipientPubKeyFromCltvPaymentChannel(lockTimeVerifyOutput.getScriptPubKey()));
              if (key1 == null || key2 == null) {
                  System.err.println("Don't own private keys for both pubkeys");
                  return;
              }
  
              TransactionInput input = new TransactionInput(
                      params, req.tx, new byte[] {}, lockTimeVerifyOutput.getOutPointFor());
              req.tx.addInput(input);
              TransactionSignature sig1 =
                      req.tx.calculateSignature(0, key1, lockTimeVerifyOutput.getScriptPubKey(), Transaction.SigHash.SINGLE, false);
              TransactionSignature sig2 =
                      req.tx.calculateSignature(0, key2, lockTimeVerifyOutput.getScriptPubKey(), Transaction.SigHash.SINGLE, false);
              input.setScriptSig(ScriptBuilder.createCLTVPaymentChannelInput(sig1, sig2));
  
              System.out.println(req.tx.getTxId());
              if (options.has("offline")) {
                  wallet.commitTx(req.tx);
                  return;
              }
  
              setup();
              peerGroup.start();
              // Wait for peers to connect, the tx to be sent to one of them and for it to be propagated across the
              // network. Once propagation is complete and we heard the transaction back from all our peers, it will
              // be committed to the wallet.
              peerGroup.broadcastTransaction(req.tx).future().get();
              // Hack for regtest/single peer mode, as we're about to shut down and won't get an ACK from the remote end.
              List<Peer> peerList = peerGroup.getConnectedPeers();
              if (peerList.size() == 1)
                  peerList.get(0).ping().get();
          } catch (BlockStoreException e) {
              throw new RuntimeException(e);
          } catch (KeyCrypterException e) {
              throw new RuntimeException(e);
          } catch (InterruptedException e) {
              throw new RuntimeException(e);
          } catch (ExecutionException e) {
              throw new RuntimeException(e);
          }
      }