Search in sources :

Example 1 with PSBTParseException

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);
    }
}
Also used : Gson(com.google.gson.Gson) URISyntaxException(java.net.URISyntaxException) URI(java.net.URI) BitcoinURI(com.sparrowwallet.drongo.uri.BitcoinURI) PSBT(com.sparrowwallet.drongo.psbt.PSBT) Proxy(java.net.Proxy) HttpURLConnection(java.net.HttpURLConnection) PSBTParseException(com.sparrowwallet.drongo.psbt.PSBTParseException)

Example 2 with PSBTParseException

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());
    }
}
Also used : BlockTransactionHashIndex(com.sparrowwallet.drongo.wallet.BlockTransactionHashIndex) PSBTParseException(com.sparrowwallet.drongo.psbt.PSBTParseException) CahootsContext(com.samourai.soroban.cahoots.CahootsContext) Transaction(com.sparrowwallet.drongo.protocol.Transaction) OnlineCahootsMessage(com.samourai.soroban.client.cahoots.OnlineCahootsMessage) SorobanCahootsService(com.samourai.soroban.client.cahoots.SorobanCahootsService) PSBTParseException(com.sparrowwallet.drongo.psbt.PSBTParseException) Cahoots(com.samourai.wallet.cahoots.Cahoots) HashMap(java.util.HashMap) Map(java.util.Map) WalletNode(com.sparrowwallet.drongo.wallet.WalletNode)

Aggregations

PSBTParseException (com.sparrowwallet.drongo.psbt.PSBTParseException)2 Gson (com.google.gson.Gson)1 CahootsContext (com.samourai.soroban.cahoots.CahootsContext)1 OnlineCahootsMessage (com.samourai.soroban.client.cahoots.OnlineCahootsMessage)1 SorobanCahootsService (com.samourai.soroban.client.cahoots.SorobanCahootsService)1 Cahoots (com.samourai.wallet.cahoots.Cahoots)1 Transaction (com.sparrowwallet.drongo.protocol.Transaction)1 PSBT (com.sparrowwallet.drongo.psbt.PSBT)1 BitcoinURI (com.sparrowwallet.drongo.uri.BitcoinURI)1 BlockTransactionHashIndex (com.sparrowwallet.drongo.wallet.BlockTransactionHashIndex)1 WalletNode (com.sparrowwallet.drongo.wallet.WalletNode)1 HttpURLConnection (java.net.HttpURLConnection)1 Proxy (java.net.Proxy)1 URI (java.net.URI)1 URISyntaxException (java.net.URISyntaxException)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1