/** * 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; }