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();
}