Java源码示例:org.bitcoin.protocols.payments.Protos

示例1
/**
 * Generates a Payment message and sends the payment to the merchant who sent the PaymentRequest.
 * Provide transactions built by the wallet.
 * NOTE: This does not broadcast the transactions to the bitcoin network, it merely sends a Payment message to the
 * merchant confirming the payment.
 * Returns an object wrapping PaymentACK once received.
 * If the PaymentRequest did not specify a payment_url, returns null and does nothing.
 *
 * @param txns       list of transactions to be included with the Payment message.
 * @param refundAddr will be used by the merchant to send money back if there was a problem.
 * @param memo       is a message to include in the payment message sent to the merchant.
 */
@Nullable
public ListenableFuture<PaymentProtocol.Ack> sendPayment(List<Transaction> txns, @Nullable Address refundAddr, @Nullable String memo)
        throws PaymentProtocolException, VerificationException, IOException {
    Protos.Payment payment = getPayment(txns, refundAddr, memo);
    if (payment == null)
        return null;
    if (isExpired())
        throw new PaymentProtocolException.Expired("PaymentRequest is expired");
    URL url;
    try {
        url = new URL(paymentDetails.getPaymentUrl());
    } catch (MalformedURLException e) {
        throw new PaymentProtocolException.InvalidPaymentURL(e);
    }
    return sendPayment(url, payment);
}
 
示例2
@VisibleForTesting
protected ListenableFuture<PaymentProtocol.Ack> sendPayment(final URL url, final Protos.Payment payment) {
    return executor.submit(new Callable<PaymentProtocol.Ack>() {
        @Override
        public PaymentProtocol.Ack call() throws Exception {
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", PaymentProtocol.MIMETYPE_PAYMENT);
            connection.setRequestProperty("Accept", PaymentProtocol.MIMETYPE_PAYMENTACK);
            connection.setRequestProperty("Content-Length", Integer.toString(payment.getSerializedSize()));
            connection.setUseCaches(false);
            connection.setDoInput(true);
            connection.setDoOutput(true);

            // Send request.
            DataOutputStream outStream = new DataOutputStream(connection.getOutputStream());
            payment.writeTo(outStream);
            outStream.flush();
            outStream.close();

            // Get response.
            Protos.PaymentACK paymentAck = Protos.PaymentACK.parseFrom(connection.getInputStream());
            return PaymentProtocol.parsePaymentAck(paymentAck);
        }
    });
}
 
示例3
/**
 * 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;
}
 
示例4
/**
 * Create a payment message. This wraps up transaction data along with anything else useful for making a payment.
 *
 * @param transactions  transactions to include with the payment message
 * @param refundOutputs list of outputs to refund coins to, or null
 * @param memo          arbitrary, user readable memo, or null if none
 * @param merchantData  arbitrary merchant data, or null if none
 * @return created payment message
 */
public static Protos.Payment createPaymentMessage(List<Transaction> transactions,
                                                  @Nullable List<Protos.Output> refundOutputs, @Nullable String memo, @Nullable byte[] merchantData) {
    Protos.Payment.Builder builder = Protos.Payment.newBuilder();
    for (Transaction transaction : transactions) {
        transaction.verify();
        builder.addTransactions(ByteString.copyFrom(transaction.unsafeBitcoinSerialize()));
    }
    if (refundOutputs != null) {
        for (Protos.Output output : refundOutputs)
            builder.addRefundTo(output);
    }
    if (memo != null)
        builder.setMemo(memo);
    if (merchantData != null)
        builder.setMerchantData(ByteString.copyFrom(merchantData));
    return builder.build();
}
 
示例5
@Test
public void testSignAndVerifyValid() throws Exception {
    Protos.PaymentRequest.Builder paymentRequest = minimalPaymentRequest().toBuilder();

    // Sign
    KeyStore keyStore = X509Utils
            .loadKeyStore("JKS", "password", getClass().getResourceAsStream("test-valid-cert"));
    PrivateKey privateKey = (PrivateKey) keyStore.getKey("test-valid", "password".toCharArray());
    X509Certificate clientCert = (X509Certificate) keyStore.getCertificate("test-valid");
    PaymentProtocol.signPaymentRequest(paymentRequest, new X509Certificate[]{clientCert}, privateKey);

    // Verify
    PkiVerificationData verificationData = PaymentProtocol.verifyPaymentRequestPki(paymentRequest.build(), caStore);
    assertNotNull(verificationData);
    assertEquals(caCert, verificationData.rootAuthority.getTrustedCert());
}
 
示例6
private Protos.PaymentRequest newSimplePaymentRequest(String netID) {
    Protos.Output.Builder outputBuilder = Protos.Output.newBuilder()
            .setAmount(coin.value)
            .setScript(ByteString.copyFrom(outputToMe.getScriptBytes()));
    Protos.PaymentDetails paymentDetails = Protos.PaymentDetails.newBuilder()
            .setNetwork(netID)
            .setTime(time)
            .setPaymentUrl(simplePaymentUrl)
            .addOutputs(outputBuilder)
            .setMemo(paymentRequestMemo)
            .setMerchantData(merchantData)
            .build();
    return Protos.PaymentRequest.newBuilder()
            .setPaymentDetailsVersion(1)
            .setPkiType("none")
            .setSerializedPaymentDetails(paymentDetails.toByteString())
            .build();
}
 
示例7
private Protos.PaymentRequest newExpiredPaymentRequest() {
    Protos.Output.Builder outputBuilder = Protos.Output.newBuilder()
            .setAmount(coin.value)
            .setScript(ByteString.copyFrom(outputToMe.getScriptBytes()));
    Protos.PaymentDetails paymentDetails = Protos.PaymentDetails.newBuilder()
            .setNetwork("test")
            .setTime(time - 10)
            .setExpires(time - 1)
            .setPaymentUrl(simplePaymentUrl)
            .addOutputs(outputBuilder)
            .setMemo(paymentRequestMemo)
            .setMerchantData(merchantData)
            .build();
    return Protos.PaymentRequest.newBuilder()
            .setPaymentDetailsVersion(1)
            .setPkiType("none")
            .setSerializedPaymentDetails(paymentDetails.toByteString())
            .build();
}
 
示例8
@Test
public void testSignAndVerifyValid() throws Exception {
    Protos.PaymentRequest.Builder paymentRequest = minimalPaymentRequest().toBuilder();

    // Sign
    KeyStore keyStore = X509Utils
            .loadKeyStore("JKS", "password", getClass().getResourceAsStream("test-valid-cert"));
    PrivateKey privateKey = (PrivateKey) keyStore.getKey("test-valid", "password".toCharArray());
    X509Certificate clientCert = (X509Certificate) keyStore.getCertificate("test-valid");
    PaymentProtocol.signPaymentRequest(paymentRequest, new X509Certificate[]{clientCert}, privateKey);

    // Verify
    PkiVerificationData verificationData = PaymentProtocol.verifyPaymentRequestPki(paymentRequest.build(), caStore);
    assertNotNull(verificationData);
    assertEquals(caCert, verificationData.rootAuthority.getTrustedCert());
}
 
示例9
/**
 * Generates a Payment message and sends the payment to the merchant who sent the PaymentRequest.
 * Provide transactions built by the wallet.
 * NOTE: This does not broadcast the transactions to the bitcoin network, it merely sends a Payment message to the
 * merchant confirming the payment.
 * Returns an object wrapping PaymentACK once received.
 * If the PaymentRequest did not specify a payment_url, returns null and does nothing.
 * @param txns list of transactions to be included with the Payment message.
 * @param refundAddr will be used by the merchant to send money back if there was a problem.
 * @param memo is a message to include in the payment message sent to the merchant.
 */
@Nullable
public ListenableFuture<PaymentProtocol.Ack> sendPayment(List<Transaction> txns, @Nullable Address refundAddr, @Nullable String memo)
        throws PaymentProtocolException, VerificationException, IOException {
    Protos.Payment payment = getPayment(txns, refundAddr, memo);
    if (payment == null)
        return null;
    if (isExpired())
        throw new PaymentProtocolException.Expired("PaymentRequest is expired");
    URL url;
    try {
        url = new URL(paymentDetails.getPaymentUrl());
    } catch (MalformedURLException e) {
        throw new PaymentProtocolException.InvalidPaymentURL(e);
    }
    return sendPayment(url, payment);
}
 
示例10
/**
 * Generates a Payment message based on the information in the PaymentRequest.
 * Provide transactions built by the wallet.
 * If the PaymentRequest did not specify a payment_url, returns null.
 * @param txns list of transactions to be included with the Payment message.
 * @param refundAddr will be used by the merchant to send money back if there was a problem.
 * @param memo is a message to include in the payment message sent to the merchant.
 */
@Nullable
public Protos.Payment getPayment(List<Transaction> txns, @Nullable Address refundAddr, @Nullable String memo)
        throws IOException, PaymentProtocolException.InvalidNetwork {
    if (paymentDetails.hasPaymentUrl()) {
        for (Transaction tx : txns) {
            // BIP70 doesn't allow for regtest in its network type. If we mismatch,
            // treat regtest transactions for a testnet payment request as a match.
            if (!tx.getParams().equals(params) &&
                (!tx.getParams().equals(RegTestParams.get()) || !params.equals(TestNet3Params.get())))
                throw new PaymentProtocolException.InvalidNetwork(params.getPaymentProtocolId());
        }
        return PaymentProtocol.createPaymentMessage(txns, totalValue, refundAddr, memo, getMerchantData());
    } else {
        return null;
    }
}
 
示例11
@VisibleForTesting
protected ListenableFuture<PaymentProtocol.Ack> sendPayment(final URL url, final Protos.Payment payment) {
    return executor.submit(new Callable<PaymentProtocol.Ack>() {
        @Override
        public PaymentProtocol.Ack call() throws Exception {
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", PaymentProtocol.MIMETYPE_PAYMENT);
            connection.setRequestProperty("Accept", PaymentProtocol.MIMETYPE_PAYMENTACK);
            connection.setRequestProperty("Content-Length", Integer.toString(payment.getSerializedSize()));
            connection.setUseCaches(false);
            connection.setDoInput(true);
            connection.setDoOutput(true);

            // Send request.
            DataOutputStream outStream = new DataOutputStream(connection.getOutputStream());
            payment.writeTo(outStream);
            outStream.flush();
            outStream.close();

            // Get response.
            Protos.PaymentACK paymentAck = Protos.PaymentACK.parseFrom(connection.getInputStream());
            return PaymentProtocol.parsePaymentAck(paymentAck);
        }
    });
}
 
示例12
private Protos.PaymentRequest newExpiredPaymentRequest() {
    Protos.Output.Builder outputBuilder = Protos.Output.newBuilder()
            .setAmount(coin.value)
            .setScript(ByteString.copyFrom(outputToMe.getScriptBytes()));
    Protos.PaymentDetails paymentDetails = Protos.PaymentDetails.newBuilder()
            .setNetwork("test")
            .setTime(time - 10)
            .setExpires(time - 1)
            .setPaymentUrl(simplePaymentUrl)
            .addOutputs(outputBuilder)
            .setMemo(paymentRequestMemo)
            .setMerchantData(merchantData)
            .build();
    return Protos.PaymentRequest.newBuilder()
            .setPaymentDetailsVersion(1)
            .setPkiType("none")
            .setSerializedPaymentDetails(paymentDetails.toByteString())
            .build();
}
 
示例13
/**
 * Create a payment message. This wraps up transaction data along with anything else useful for making a payment.
 * 
 * @param transactions transactions to include with the payment message
 * @param refundOutputs list of outputs to refund coins to, or null
 * @param memo arbitrary, user readable memo, or null if none
 * @param merchantData arbitrary merchant data, or null if none
 * @return created payment message
 */
public static Protos.Payment createPaymentMessage(List<Transaction> transactions,
        @Nullable List<Protos.Output> refundOutputs, @Nullable String memo, @Nullable byte[] merchantData) {
    Protos.Payment.Builder builder = Protos.Payment.newBuilder();
    for (Transaction transaction : transactions) {
        transaction.verify();
        builder.addTransactions(ByteString.copyFrom(transaction.unsafeBitcoinSerialize()));
    }
    if (refundOutputs != null) {
        for (Protos.Output output : refundOutputs)
            builder.addRefundTo(output);
    }
    if (memo != null)
        builder.setMemo(memo);
    if (merchantData != null)
        builder.setMerchantData(ByteString.copyFrom(merchantData));
    return builder.build();
}
 
示例14
@Test
public void testDefaults() throws Exception {
    Protos.Output.Builder outputBuilder = Protos.Output.newBuilder()
            .setScript(ByteString.copyFrom(outputToMe.getScriptBytes()));
    Protos.PaymentDetails paymentDetails = Protos.PaymentDetails.newBuilder()
            .setTime(time)
            .addOutputs(outputBuilder)
            .build();
    Protos.PaymentRequest paymentRequest = Protos.PaymentRequest.newBuilder()
            .setSerializedPaymentDetails(paymentDetails.toByteString())
            .build();
    MockPaymentSession paymentSession = new MockPaymentSession(paymentRequest);
    assertEquals(Coin.ZERO, paymentSession.getValue());
    assertNull(paymentSession.getPaymentUrl());
    assertNull(paymentSession.getMemo());
}
 
示例15
private Protos.PaymentRequest newSimplePaymentRequest(String netID) {
    Protos.Output.Builder outputBuilder = Protos.Output.newBuilder()
            .setAmount(coin.value)
            .setScript(ByteString.copyFrom(outputToMe.getScriptBytes()));
    Protos.PaymentDetails paymentDetails = Protos.PaymentDetails.newBuilder()
            .setNetwork(netID)
            .setTime(time)
            .setPaymentUrl(simplePaymentUrl)
            .addOutputs(outputBuilder)
            .setMemo(paymentRequestMemo)
            .setMerchantData(merchantData)
            .build();
    return Protos.PaymentRequest.newBuilder()
            .setPaymentDetailsVersion(1)
            .setPkiType("none")
            .setSerializedPaymentDetails(paymentDetails.toByteString())
            .build();
}
 
示例16
private Protos.PaymentRequest newExpiredPaymentRequest() {
    Protos.Output.Builder outputBuilder = Protos.Output.newBuilder()
            .setAmount(coin.value)
            .setScript(ByteString.copyFrom(outputToMe.getScriptBytes()));
    Protos.PaymentDetails paymentDetails = Protos.PaymentDetails.newBuilder()
            .setNetwork("test")
            .setTime(time - 10)
            .setExpires(time - 1)
            .setPaymentUrl(simplePaymentUrl)
            .addOutputs(outputBuilder)
            .setMemo(paymentRequestMemo)
            .setMerchantData(merchantData)
            .build();
    return Protos.PaymentRequest.newBuilder()
            .setPaymentDetailsVersion(1)
            .setPkiType("none")
            .setSerializedPaymentDetails(paymentDetails.toByteString())
            .build();
}
 
示例17
@Test
public void testSignAndVerifyValid() throws Exception {
    Protos.PaymentRequest.Builder paymentRequest = minimalPaymentRequest().toBuilder();

    // Sign
    KeyStore keyStore = X509Utils
            .loadKeyStore("JKS", "password", getClass().getResourceAsStream("test-valid-cert"));
    PrivateKey privateKey = (PrivateKey) keyStore.getKey("test-valid", "password".toCharArray());
    X509Certificate clientCert = (X509Certificate) keyStore.getCertificate("test-valid");
    PaymentProtocol.signPaymentRequest(paymentRequest, new X509Certificate[]{clientCert}, privateKey);

    // Verify
    PkiVerificationData verificationData = PaymentProtocol.verifyPaymentRequestPki(paymentRequest.build(), caStore);
    assertNotNull(verificationData);
    assertEquals(caCert, verificationData.rootAuthority.getTrustedCert());
}
 
示例18
/**
 * Create a payment message. This wraps up transaction data along with anything else useful for making a payment.
 * 
 * @param transactions transactions to include with the payment message
 * @param refundOutputs list of outputs to refund coins to, or null
 * @param memo arbitrary, user readable memo, or null if none
 * @param merchantData arbitrary merchant data, or null if none
 * @return created payment message
 */
public static Protos.Payment createPaymentMessage(List<Transaction> transactions,
        @Nullable List<Protos.Output> refundOutputs, @Nullable String memo, @Nullable byte[] merchantData) {
    Protos.Payment.Builder builder = Protos.Payment.newBuilder();
    for (Transaction transaction : transactions) {
        transaction.verify();
        builder.addTransactions(ByteString.copyFrom(transaction.unsafeBitcoinSerialize()));
    }
    if (refundOutputs != null) {
        for (Protos.Output output : refundOutputs)
            builder.addRefundTo(output);
    }
    if (memo != null)
        builder.setMemo(memo);
    if (merchantData != null)
        builder.setMerchantData(ByteString.copyFrom(merchantData));
    return builder.build();
}
 
示例19
/**
 * 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;
}
 
示例20
@VisibleForTesting
protected ListenableFuture<PaymentProtocol.Ack> sendPayment(final URL url, final Protos.Payment payment) {
    return executor.submit(new Callable<PaymentProtocol.Ack>() {
        @Override
        public PaymentProtocol.Ack call() throws Exception {
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", PaymentProtocol.MIMETYPE_PAYMENT);
            connection.setRequestProperty("Accept", PaymentProtocol.MIMETYPE_PAYMENTACK);
            connection.setRequestProperty("Content-Length", Integer.toString(payment.getSerializedSize()));
            connection.setUseCaches(false);
            connection.setDoInput(true);
            connection.setDoOutput(true);

            // Send request.
            DataOutputStream outStream = new DataOutputStream(connection.getOutputStream());
            payment.writeTo(outStream);
            outStream.flush();
            outStream.close();

            // Get response.
            Protos.PaymentACK paymentAck = Protos.PaymentACK.parseFrom(connection.getInputStream());
            return PaymentProtocol.parsePaymentAck(paymentAck);
        }
    });
}
 
示例21
private static ListenableFuture<PaymentSession> fetchPaymentRequest(final URI uri, final boolean verifyPki, @Nullable final TrustStoreLoader trustStoreLoader) {
    return executor.submit(new Callable<PaymentSession>() {
        @Override
        public PaymentSession call() throws Exception {
            HttpURLConnection connection = (HttpURLConnection) uri.toURL().openConnection();
            connection.setRequestProperty("Accept", PaymentProtocol.MIMETYPE_PAYMENTREQUEST);
            connection.setUseCaches(false);
            Protos.PaymentRequest paymentRequest = Protos.PaymentRequest.parseFrom(connection.getInputStream());
            return new PaymentSession(paymentRequest, verifyPki, trustStoreLoader);
        }
    });
}
 
示例22
/**
 * Returns the outputs of the payment request.
 */
public List<PaymentProtocol.Output> getOutputs() {
    List<PaymentProtocol.Output> outputs = new ArrayList<>(paymentDetails.getOutputsCount());
    for (Protos.Output output : paymentDetails.getOutputsList()) {
        Coin amount = output.hasAmount() ? Coin.valueOf(output.getAmount()) : null;
        outputs.add(new PaymentProtocol.Output(amount, output.getScript().toByteArray()));
    }
    return outputs;
}
 
示例23
@Test
public void testPkiVerification() throws Exception {
    InputStream in = getClass().getResourceAsStream("pki_test.bitcoinpaymentrequest");
    Protos.PaymentRequest paymentRequest = Protos.PaymentRequest.newBuilder().mergeFrom(in).build();
    PaymentProtocol.PkiVerificationData pkiData = PaymentProtocol.verifyPaymentRequestPki(paymentRequest,
            new TrustStoreLoader.DefaultTrustStoreLoader().getKeyStore());
    assertEquals("www.bitcoincore.org", pkiData.displayName);
    assertEquals("The USERTRUST Network, Salt Lake City, US", pkiData.rootAuthorityName);
}
 
示例24
/**
 * 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<>(paymentMessage.getTransactionsCount());
    for (final ByteString transaction : paymentMessage.getTransactionsList())
        transactions.add(params.getDefaultSerializer().makeTransaction(transaction.toByteArray()));
    return transactions;
}
 
示例25
private void parsePaymentRequest(Protos.PaymentRequest request) throws PaymentProtocolException {
    try {
        if (request == null)
            throw new PaymentProtocolException("request cannot be null");
        if (request.getPaymentDetailsVersion() != 1)
            throw new PaymentProtocolException.InvalidVersion("Version 1 required. Received version " + request.getPaymentDetailsVersion());
        paymentRequest = request;
        if (!request.hasSerializedPaymentDetails())
            throw new PaymentProtocolException("No PaymentDetails");
        paymentDetails = Protos.PaymentDetails.newBuilder().mergeFrom(request.getSerializedPaymentDetails()).build();
        if (paymentDetails == null)
            throw new PaymentProtocolException("Invalid PaymentDetails");
        if (!paymentDetails.hasNetwork())
            params = MainNetParams.get();
        else
            params = NetworkParameters.fromPmtProtocolID(paymentDetails.getNetwork());
        if (params == null)
            throw new PaymentProtocolException.InvalidNetwork("Invalid network " + paymentDetails.getNetwork());
        if (paymentDetails.getOutputsCount() < 1)
            throw new PaymentProtocolException.InvalidOutputs("No outputs");
        for (Protos.Output output : paymentDetails.getOutputsList()) {
            if (output.hasAmount())
                totalValue = totalValue.add(Coin.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 (params.hasMaxMoney() && totalValue.compareTo(params.getMaxMoney()) > 0)
            throw new PaymentProtocolException.InvalidOutputs("The outputs are way too big.");
    } catch (InvalidProtocolBufferException e) {
        throw new PaymentProtocolException(e);
    }
}
 
示例26
@Test
public void testSimplePayment() throws Exception {
    // Create a PaymentRequest and make sure the correct values are parsed by the PaymentSession.
    MockPaymentSession paymentSession = new MockPaymentSession(newSimplePaymentRequest("test"));
    assertEquals(paymentRequestMemo, paymentSession.getMemo());
    assertEquals(coin, paymentSession.getValue());
    assertEquals(simplePaymentUrl, paymentSession.getPaymentUrl());
    assertTrue(new Date(time * 1000L).equals(paymentSession.getDate()));
    assertTrue(paymentSession.getSendRequest().tx.equals(tx));
    assertFalse(paymentSession.isExpired());

    // Send the payment and verify that the correct information is sent.
    // Add a dummy input to tx so it is considered valid.
    tx.addInput(new TransactionInput(PARAMS, tx, outputToMe.getScriptBytes()));
    ArrayList<Transaction> txns = new ArrayList<>();
    txns.add(tx);
    Address refundAddr = new Address(PARAMS, serverKey.getPubKeyHash());
    paymentSession.sendPayment(txns, refundAddr, paymentMemo);
    assertEquals(1, paymentSession.getPaymentLog().size());
    assertEquals(simplePaymentUrl, paymentSession.getPaymentLog().get(0).getUrl().toString());
    Protos.Payment payment = paymentSession.getPaymentLog().get(0).getPayment();
    assertEquals(paymentMemo, payment.getMemo());
    assertEquals(merchantData, payment.getMerchantData());
    assertEquals(1, payment.getRefundToCount());
    assertEquals(coin.value, payment.getRefundTo(0).getAmount());
    TransactionOutput refundOutput = new TransactionOutput(PARAMS, null, coin, refundAddr);
    ByteString refundScript = ByteString.copyFrom(refundOutput.getScriptBytes());
    assertTrue(refundScript.equals(payment.getRefundTo(0).getScript()));
}
 
示例27
/**
 * Sign the provided payment request.
 *
 * @param paymentRequest   Payment request to sign, in its builder form.
 * @param certificateChain Certificate chain to send with the payment request, ordered from client certificate to root
 *                         certificate. The root certificate itself may be omitted.
 * @param privateKey       The key to sign with. Must match the public key from the first certificate of the certificate chain.
 */
public static void signPaymentRequest(Protos.PaymentRequest.Builder paymentRequest,
                                      X509Certificate[] certificateChain, PrivateKey privateKey) {
    try {
        final Protos.X509Certificates.Builder certificates = Protos.X509Certificates.newBuilder();
        for (final Certificate certificate : certificateChain)
            certificates.addCertificate(ByteString.copyFrom(certificate.getEncoded()));

        paymentRequest.setPkiType("x509+sha256");
        paymentRequest.setPkiData(certificates.build().toByteString());
        paymentRequest.setSignature(ByteString.EMPTY);
        final Protos.PaymentRequest paymentRequestToSign = paymentRequest.build();

        final String algorithm;
        if ("RSA".equalsIgnoreCase(privateKey.getAlgorithm()))
            algorithm = "SHA256withRSA";
        else
            throw new IllegalStateException(privateKey.getAlgorithm());

        final Signature signature = Signature.getInstance(algorithm);
        signature.initSign(privateKey);
        signature.update(paymentRequestToSign.toByteArray());

        paymentRequest.setSignature(ByteString.copyFrom(signature.sign()));
    } catch (final GeneralSecurityException x) {
        // Should never happen so don't make users have to think about it.
        throw new RuntimeException(x);
    }
}
 
示例28
/**
 * Create a payment message with one standard pay to address output.
 *
 * @param transactions  one or more transactions that satisfy the requested outputs.
 * @param refundAmount  amount of coins to request as a refund, or null if no refund.
 * @param refundAddress address to refund coins to
 * @param memo          arbitrary, user readable memo, or null if none
 * @param merchantData  arbitrary merchant data, or null if none
 * @return created payment message
 */
public static Protos.Payment createPaymentMessage(List<Transaction> transactions,
                                                  @Nullable Coin refundAmount, @Nullable Address refundAddress, @Nullable String memo,
                                                  @Nullable byte[] merchantData) {
    if (refundAddress != null) {
        if (refundAmount == null)
            throw new IllegalArgumentException("Specify refund amount if refund address is specified.");
        return createPaymentMessage(transactions,
                ImmutableList.of(createPayToAddressOutput(refundAmount, refundAddress)), memo, merchantData);
    } else {
        return createPaymentMessage(transactions, null, memo, merchantData);
    }
}
 
示例29
/**
 * 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<>(paymentMessage.getTransactionsCount());
    for (final ByteString transaction : paymentMessage.getTransactionsList())
        transactions.add(params.getDefaultSerializer().makeTransaction(transaction.toByteArray()));
    return transactions;
}
 
示例30
/**
 * Create a payment ack.
 *
 * @param paymentMessage payment message to send with the ack
 * @param memo           arbitrary, user readable memo, or null if none
 * @return created payment ack
 */
public static Protos.PaymentACK createPaymentAck(Protos.Payment paymentMessage, @Nullable String memo) {
    final Protos.PaymentACK.Builder builder = Protos.PaymentACK.newBuilder();
    builder.setPayment(paymentMessage);
    if (memo != null)
        builder.setMemo(memo);
    return builder.build();
}