Search in sources :

Example 1 with WalletResponse

use of com.samourai.wallet.api.backend.beans.WalletResponse in project sparrow by sparrowwallet.

the class SparrowDataSource method fetchWalletResponse.

@Override
protected WalletResponse fetchWalletResponse() throws Exception {
    WalletResponse walletResponse = new WalletResponse();
    walletResponse.wallet = new WalletResponse.Wallet();
    Map<Sha256Hash, BlockTransaction> allTransactions = new HashMap<>();
    Map<Sha256Hash, String> allTransactionsZpubs = new HashMap<>();
    List<WalletResponse.Address> addresses = new ArrayList<>();
    List<WalletResponse.Tx> txes = new ArrayList<>();
    List<UnspentOutput> unspentOutputs = new ArrayList<>();
    int storedBlockHeight = 0;
    String[] zpubs = getWalletSupplier().getPubs(true);
    for (String zpub : zpubs) {
        Wallet wallet = getWallet(zpub);
        if (wallet == null) {
            log.debug("No wallet for " + zpub + " found");
            continue;
        }
        Map<Sha256Hash, BlockTransaction> walletTransactions = wallet.getWalletTransactions();
        allTransactions.putAll(walletTransactions);
        walletTransactions.keySet().forEach(txid -> allTransactionsZpubs.put(txid, zpub));
        if (wallet.getStoredBlockHeight() != null) {
            storedBlockHeight = Math.max(storedBlockHeight, wallet.getStoredBlockHeight());
        }
        WalletResponse.Address address = new WalletResponse.Address();
        List<ExtendedKey.Header> headers = ExtendedKey.Header.getHeaders(Network.get());
        ExtendedKey.Header header = headers.stream().filter(head -> head.getDefaultScriptType().equals(wallet.getScriptType()) && !head.isPrivateKey()).findFirst().orElse(ExtendedKey.Header.xpub);
        address.address = wallet.getKeystores().get(0).getExtendedPublicKey().toString(header);
        int receiveIndex = wallet.getNode(KeyPurpose.RECEIVE).getHighestUsedIndex() == null ? 0 : wallet.getNode(KeyPurpose.RECEIVE).getHighestUsedIndex() + 1;
        address.account_index = wallet.getMixConfig() != null ? Math.max(receiveIndex, wallet.getMixConfig().getReceiveIndex()) : receiveIndex;
        int changeIndex = wallet.getNode(KeyPurpose.CHANGE).getHighestUsedIndex() == null ? 0 : wallet.getNode(KeyPurpose.CHANGE).getHighestUsedIndex() + 1;
        address.change_index = wallet.getMixConfig() != null ? Math.max(changeIndex, wallet.getMixConfig().getChangeIndex()) : changeIndex;
        address.n_tx = walletTransactions.size();
        addresses.add(address);
        for (Map.Entry<BlockTransactionHashIndex, WalletNode> utxo : wallet.getWalletUtxos().entrySet()) {
            BlockTransaction blockTransaction = wallet.getWalletTransaction(utxo.getKey().getHash());
            if (blockTransaction != null && utxo.getKey().getStatus() != Status.FROZEN) {
                unspentOutputs.add(Whirlpool.getUnspentOutput(utxo.getValue(), blockTransaction, (int) utxo.getKey().getIndex()));
            }
        }
    }
    for (BlockTransaction blockTransaction : allTransactions.values()) {
        WalletResponse.Tx tx = new WalletResponse.Tx();
        tx.block_height = blockTransaction.getHeight();
        tx.hash = blockTransaction.getHashAsString();
        tx.locktime = blockTransaction.getTransaction().getLocktime();
        tx.version = (int) blockTransaction.getTransaction().getVersion();
        tx.inputs = new WalletResponse.TxInput[blockTransaction.getTransaction().getInputs().size()];
        for (int i = 0; i < blockTransaction.getTransaction().getInputs().size(); i++) {
            TransactionInput txInput = blockTransaction.getTransaction().getInputs().get(i);
            tx.inputs[i] = new WalletResponse.TxInput();
            tx.inputs[i].vin = txInput.getIndex();
            tx.inputs[i].sequence = txInput.getSequenceNumber();
            if (allTransactionsZpubs.containsKey(txInput.getOutpoint().getHash())) {
                tx.inputs[i].prev_out = new WalletResponse.TxOut();
                tx.inputs[i].prev_out.txid = txInput.getOutpoint().getHash().toString();
                tx.inputs[i].prev_out.vout = (int) txInput.getOutpoint().getIndex();
                BlockTransaction spentTransaction = allTransactions.get(txInput.getOutpoint().getHash());
                if (spentTransaction != null) {
                    TransactionOutput spentOutput = spentTransaction.getTransaction().getOutputs().get((int) txInput.getOutpoint().getIndex());
                    tx.inputs[i].prev_out.value = spentOutput.getValue();
                }
                tx.inputs[i].prev_out.xpub = new UnspentOutput.Xpub();
                tx.inputs[i].prev_out.xpub.m = allTransactionsZpubs.get(txInput.getOutpoint().getHash());
            }
        }
        tx.out = new WalletResponse.TxOutput[blockTransaction.getTransaction().getOutputs().size()];
        for (int i = 0; i < blockTransaction.getTransaction().getOutputs().size(); i++) {
            TransactionOutput txOutput = blockTransaction.getTransaction().getOutputs().get(i);
            tx.out[i] = new WalletResponse.TxOutput();
            tx.out[i].n = txOutput.getIndex();
            tx.out[i].value = txOutput.getValue();
            tx.out[i].xpub = new UnspentOutput.Xpub();
            tx.out[i].xpub.m = allTransactionsZpubs.get(blockTransaction.getHash());
        }
        txes.add(tx);
    }
    walletResponse.addresses = addresses.toArray(new WalletResponse.Address[0]);
    walletResponse.txs = txes.toArray(new WalletResponse.Tx[0]);
    walletResponse.unspent_outputs = unspentOutputs.toArray(new UnspentOutput[0]);
    walletResponse.info = new WalletResponse.Info();
    walletResponse.info.latest_block = new WalletResponse.InfoBlock();
    walletResponse.info.latest_block.height = AppServices.getCurrentBlockHeight() == null ? storedBlockHeight : AppServices.getCurrentBlockHeight();
    walletResponse.info.latest_block.hash = Sha256Hash.ZERO_HASH.toString();
    walletResponse.info.latest_block.time = AppServices.getLatestBlockHeader() == null ? 1 : AppServices.getLatestBlockHeader().getTime();
    walletResponse.info.fees = new LinkedHashMap<>();
    for (MinerFeeTarget target : MinerFeeTarget.values()) {
        walletResponse.info.fees.put(target.getValue(), getMinerFeeSupplier().getFee(target));
    }
    return walletResponse;
}
Also used : TransactionOutput(com.sparrowwallet.drongo.protocol.TransactionOutput) WalletResponse(com.samourai.wallet.api.backend.beans.WalletResponse) Sha256Hash(com.sparrowwallet.drongo.protocol.Sha256Hash) UnspentOutput(com.samourai.wallet.api.backend.beans.UnspentOutput) TransactionInput(com.sparrowwallet.drongo.protocol.TransactionInput) MinerFeeTarget(com.samourai.wallet.api.backend.MinerFeeTarget) WhirlpoolWallet(com.samourai.whirlpool.client.wallet.WhirlpoolWallet) HD_Wallet(com.samourai.wallet.hd.HD_Wallet) ExtendedKey(com.sparrowwallet.drongo.ExtendedKey)

Aggregations

MinerFeeTarget (com.samourai.wallet.api.backend.MinerFeeTarget)1 UnspentOutput (com.samourai.wallet.api.backend.beans.UnspentOutput)1 WalletResponse (com.samourai.wallet.api.backend.beans.WalletResponse)1 HD_Wallet (com.samourai.wallet.hd.HD_Wallet)1 WhirlpoolWallet (com.samourai.whirlpool.client.wallet.WhirlpoolWallet)1 ExtendedKey (com.sparrowwallet.drongo.ExtendedKey)1 Sha256Hash (com.sparrowwallet.drongo.protocol.Sha256Hash)1 TransactionInput (com.sparrowwallet.drongo.protocol.TransactionInput)1 TransactionOutput (com.sparrowwallet.drongo.protocol.TransactionOutput)1