use of com.sparrowwallet.drongo.psbt.PSBTParseException in project sparrow by sparrowwallet.
the class Payjoin method requestPayjoinPSBT.
public PSBT requestPayjoinPSBT(boolean allowOutputSubstitution) throws PayjoinReceiverException {
if (!payjoinURI.isPayjoinOutputSubstitutionAllowed()) {
allowOutputSubstitution = false;
}
URI uri = payjoinURI.getPayjoinUrl();
if (uri == null) {
log.error("No payjoin URL provided");
throw new PayjoinReceiverException("No payjoin URL provided");
}
try {
String base64Psbt = psbt.getPublicCopy().toBase64String();
String appendQuery = "v=1";
int changeOutputIndex = getChangeOutputIndex();
long maxAdditionalFeeContribution = 0;
if (changeOutputIndex > -1) {
appendQuery += "&additionalfeeoutputindex=" + changeOutputIndex;
maxAdditionalFeeContribution = getAdditionalFeeContribution();
appendQuery += "&maxadditionalfeecontribution=" + maxAdditionalFeeContribution;
}
URI finalUri = new URI(uri.getScheme(), uri.getAuthority(), uri.getPath(), uri.getQuery() == null ? appendQuery : uri.getQuery() + "&" + appendQuery, uri.getFragment());
log.info("Sending PSBT to " + finalUri.toURL());
Proxy proxy = AppServices.getProxy();
HttpURLConnection connection = proxy == null ? (HttpURLConnection) finalUri.toURL().openConnection() : (HttpURLConnection) finalUri.toURL().openConnection(proxy);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "text/plain");
connection.setDoOutput(true);
try (OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream())) {
writer.write(base64Psbt);
writer.flush();
}
StringBuilder response = new StringBuilder();
try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8))) {
String responseLine;
while ((responseLine = br.readLine()) != null) {
response.append(responseLine.trim());
}
}
int statusCode = connection.getResponseCode();
if (statusCode != 200) {
Gson gson = new Gson();
PayjoinReceiverError payjoinReceiverError = gson.fromJson(response.toString(), PayjoinReceiverError.class);
log.warn("Payjoin receiver returned an error of " + payjoinReceiverError.getErrorCode() + " (" + payjoinReceiverError.getMessage() + ")");
throw new PayjoinReceiverException(payjoinReceiverError.getSafeMessage());
}
PSBT proposalPsbt = PSBT.fromString(response.toString().trim());
checkProposal(psbt, proposalPsbt, changeOutputIndex, maxAdditionalFeeContribution, allowOutputSubstitution);
return proposalPsbt;
} catch (URISyntaxException e) {
log.error("Invalid payjoin receiver URI", e);
throw new PayjoinReceiverException("Invalid payjoin receiver URI", e);
} catch (IOException e) {
log.error("Payjoin receiver error", e);
throw new PayjoinReceiverException("Payjoin receiver error", e);
} catch (PSBTParseException e) {
log.error("Error parsing received PSBT", e);
throw new PayjoinReceiverException("Payjoin receiver returned invalid PSBT", e);
}
}
use of com.sparrowwallet.drongo.psbt.PSBTParseException in project sparrow by sparrowwallet.
the class CounterpartyController method startCounterpartyCollaboration.
private void startCounterpartyCollaboration(SparrowCahootsWallet counterpartyCahootsWallet, PaymentCode initiatorPaymentCode, CahootsType cahootsType) {
sorobanProgressLabel.setText("Creating mix transaction...");
Soroban soroban = AppServices.getSorobanServices().getSoroban(walletId);
Map<BlockTransactionHashIndex, WalletNode> walletUtxos = wallet.getWalletUtxos();
for (Map.Entry<BlockTransactionHashIndex, WalletNode> entry : walletUtxos.entrySet()) {
if (entry.getKey().getStatus() != Status.FROZEN) {
counterpartyCahootsWallet.addUtxo(entry.getValue(), wallet.getWalletTransaction(entry.getKey().getHash()), (int) entry.getKey().getIndex());
}
}
try {
SorobanCahootsService sorobanCahootsService = soroban.getSorobanCahootsService(counterpartyCahootsWallet);
CahootsContext cahootsContext = cahootsType == CahootsType.STONEWALLX2 ? CahootsContext.newCounterpartyStonewallx2() : CahootsContext.newCounterpartyStowaway();
sorobanCahootsService.contributor(counterpartyCahootsWallet.getAccount(), cahootsContext, initiatorPaymentCode, TIMEOUT_MS).subscribeOn(Schedulers.io()).observeOn(JavaFxScheduler.platform()).subscribe(sorobanMessage -> {
OnlineCahootsMessage cahootsMessage = (OnlineCahootsMessage) sorobanMessage;
if (cahootsMessage != null) {
Cahoots cahoots = cahootsMessage.getCahoots();
sorobanProgressBar.setProgress((double) (cahoots.getStep() + 1) / 5);
if (cahoots.getStep() == 3) {
sorobanProgressLabel.setText("Your mix partner is reviewing the transaction...");
step3Timer.start();
} else if (cahoots.getStep() >= 4) {
try {
Transaction transaction = getTransaction(cahoots);
if (transaction != null) {
transactionProperty.set(transaction);
updateTransactionDiagram(transactionDiagram, wallet, null, transaction);
next();
}
} catch (PSBTParseException e) {
log.error("Invalid collaborative PSBT created", e);
step3Desc.setText("Invalid transaction created.");
sorobanProgressLabel.setVisible(false);
}
}
}
}, error -> {
log.error("Error creating mix transaction", error);
String cutFrom = "Exception: ";
int index = error.getMessage().lastIndexOf(cutFrom);
String msg = index < 0 ? error.getMessage() : error.getMessage().substring(index + cutFrom.length());
msg = msg.replace("#Cahoots", "mix transaction");
step3Desc.setText(msg);
sorobanProgressLabel.setVisible(false);
});
} catch (Exception e) {
log.error("Error creating mix transaction", e);
sorobanProgressLabel.setText(e.getMessage());
}
}
Aggregations