/**
  * Create a standard pay to address output for usage in {@link #createPaymentRequest} and {@link
  * #createPaymentMessage}.
  *
  * @param amount amount to pay, or null
  * @param address address to pay to
  * @return output
  */
 public static Protos.Output createPayToAddressOutput(@Nullable Coin amount, Address address) {
   Protos.Output.Builder output = Protos.Output.newBuilder();
   if (amount != null) {
     final NetworkParameters params = address.getParameters();
     if (params.hasMaxMoney() && amount.compareTo(params.getMaxMoney()) > 0)
       throw new IllegalArgumentException("Amount too big: " + amount);
     output.setAmount(amount.value);
   } else {
     output.setAmount(0);
   }
   output.setScript(ByteString.copyFrom(ScriptBuilder.createOutputScript(address).getProgram()));
   return output.build();
 }
 private void parsePaymentRequest(Protos.PaymentRequest request) throws PaymentRequestException {
   try {
     if (request == null) throw new PaymentRequestException("request cannot be null");
     if (request.getPaymentDetailsVersion() != 1)
       throw new PaymentRequestException.InvalidVersion(
           "Version 1 required. Received version " + request.getPaymentDetailsVersion());
     paymentRequest = request;
     if (!request.hasSerializedPaymentDetails())
       throw new PaymentRequestException("No PaymentDetails");
     paymentDetails =
         Protos.PaymentDetails.newBuilder()
             .mergeFrom(request.getSerializedPaymentDetails())
             .build();
     if (paymentDetails == null) throw new PaymentRequestException("Invalid PaymentDetails");
     if (!paymentDetails.hasNetwork()) params = MainNetParams.get();
     else params = NetworkParameters.fromPmtProtocolID(paymentDetails.getNetwork());
     if (params == null)
       throw new PaymentRequestException.InvalidNetwork(
           "Invalid network " + paymentDetails.getNetwork());
     if (paymentDetails.getOutputsCount() < 1)
       throw new PaymentRequestException.InvalidOutputs("No outputs");
     for (Protos.Output output : paymentDetails.getOutputsList()) {
       if (output.hasAmount()) totalValue = totalValue.add(BigInteger.valueOf(output.getAmount()));
     }
     // This won't ever happen in practice. It would only happen if the user provided outputs
     // that are obviously invalid. Still, we don't want to silently overflow.
     if (totalValue.compareTo(NetworkParameters.MAX_MONEY) > 0)
       throw new PaymentRequestException.InvalidOutputs("The outputs are way too big.");
   } catch (InvalidProtocolBufferException e) {
     throw new PaymentRequestException(e);
   }
 }
 /**
  * Parse transactions from payment message.
  *
  * @param params network parameters (needed for transaction deserialization)
  * @param paymentMessage payment message to parse
  * @return list of transactions
  */
 public static List<Transaction> parseTransactionsFromPaymentMessage(
     NetworkParameters params, Protos.Payment paymentMessage) {
   final List<Transaction> transactions =
       new ArrayList<Transaction>(paymentMessage.getTransactionsCount());
   for (final ByteString transaction : paymentMessage.getTransactionsList())
     transactions.add(params.getDefaultSerializer().makeTransaction(transaction.toByteArray()));
   return transactions;
 }
  /**
   * Create a payment request. You may want to sign the request using {@link #signPaymentRequest}.
   * Use {@link Protos.PaymentRequest.Builder#build} to get the actual payment request.
   *
   * @param params network parameters
   * @param outputs list of outputs to request coins to
   * @param memo arbitrary, user readable memo, or null if none
   * @param paymentUrl URL to send payment message to, or null if none
   * @param merchantData arbitrary merchant data, or null if none
   * @return created payment request, in its builder form
   */
  public static Protos.PaymentRequest.Builder createPaymentRequest(
      NetworkParameters params,
      List<Protos.Output> outputs,
      @Nullable String memo,
      @Nullable String paymentUrl,
      @Nullable byte[] merchantData) {
    final Protos.PaymentDetails.Builder paymentDetails = Protos.PaymentDetails.newBuilder();
    paymentDetails.setNetwork(params.getPaymentProtocolId());
    for (Protos.Output output : outputs) paymentDetails.addOutputs(output);
    if (memo != null) paymentDetails.setMemo(memo);
    if (paymentUrl != null) paymentDetails.setPaymentUrl(paymentUrl);
    if (merchantData != null) paymentDetails.setMerchantData(ByteString.copyFrom(merchantData));
    paymentDetails.setTime(Utils.currentTimeSeconds());

    final Protos.PaymentRequest.Builder paymentRequest = Protos.PaymentRequest.newBuilder();
    paymentRequest.setSerializedPaymentDetails(paymentDetails.build().toByteString());
    return paymentRequest;
  }