Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,31 @@ public interface BlockchainDataSource {
*/
List<InputBox> getUnconfirmedUnspentBoxesFor(Address address, int offset, int limit);

/**
* Get all unspent boxes in the current node wallet, without unconfirmed boxes
* @return List of input boxes representing all known
*/
List<InputBox> getUnspentWalletBoxes();
/**
* Get all unspent boxes in the current node wallet, without unconfirmed boxes
* @param minConfirmations Minimum number of confirmations for a box to be included in the returned list
* @param minInclusionHeight Minimum creation height for a box to be included in the returned list
* @return List of input boxes representing all known
*/
List<InputBox> getUnspentWalletBoxes(int minConfirmations, int minInclusionHeight);

/**
* Get all unspent boxes in the current node wallet, including unconfirmed boxes from the MemPool
* @return List of all unspent boxes in this node's current wallet
*/
List<InputBox> getUnconfirmedUnspentWalletBoxes();
/**
* Get all unspent boxes in the current node wallet, including unconfirmed boxes from the MemPool
* @param minInclusionHeight Minimum creation height for a box to be included in the returned list
* @return List of all unspent boxes in this node's current wallet
*/
List<InputBox> getUnconfirmedUnspentWalletBoxes(int minInclusionHeight);

/**
* @return unconfirmed transactions from mempool
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package org.ergoplatform.appkit;

import javax.annotation.Nonnull;
import java.util.List;

/**
* {@link BoxOperations.IUnspentBoxesLoader} implementation to be used with
* {@link BoxOperations#withInputBoxesLoader(BoxOperations.IUnspentBoxesLoader)}
* <p>
* Pre-loads all boxes from node wallet, then returns pages of boxes from the master list.
* May optionally allow boxes to be grabbed from the MemPool as well.
*/
public class NodeWalletUnspentBoxesLoader implements BoxOperations.IUnspentBoxesLoader {
private List<InputBox> allBoxes;
private boolean withMemPoolBoxes = false;

public NodeWalletUnspentBoxesLoader withMemPoolBoxes(boolean withMemPoolBoxes) {
this.withMemPoolBoxes = withMemPoolBoxes;
return this;
}

public List<InputBox> getAllBoxes() {
return allBoxes;
}

@Override
public void prepare(@Nonnull BlockchainContext ctx, List<Address> addresses, long grossAmount, @Nonnull List<ErgoToken> tokensToSpend) {
BlockchainDataSource dataSource = ctx.getDataSource();
if(withMemPoolBoxes)
allBoxes = dataSource.getUnconfirmedUnspentWalletBoxes();
else
allBoxes = dataSource.getUnspentWalletBoxes();
}

@Override
public void prepareForAddress(Address address) {
// Do nothing, actual address used will be from node wallet anyway
// Maybe interface should be changed to be more abstracted? Or a separate interface is needed?
}

@Nonnull
@Override
public List<InputBox> loadBoxesPage(@Nonnull BlockchainContext ctx, @Nonnull Address sender, @Nonnull Integer page) {
int currentOffset = ctx.DEFAULT_LIMIT_FOR_API * page;
int pageEndIndex = currentOffset + ctx.DEFAULT_LIMIT_FOR_API;

if(currentOffset > allBoxes.size())
return allBoxes.subList(0,0); // Return empty list in case current offset is greater than ending index

if(pageEndIndex > allBoxes.size())
pageEndIndex = allBoxes.size(); // Shorten returned list to last index in case pageEndIndex is greater than size of list

return allBoxes.subList(currentOffset, pageEndIndex);
}
}


Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,7 @@
import org.ergoplatform.explorer.client.ExplorerApiClient;
import org.ergoplatform.explorer.client.model.OutputInfo;
import org.ergoplatform.explorer.client.model.TransactionInfo;
import org.ergoplatform.restapi.client.ApiClient;
import org.ergoplatform.restapi.client.BlocksApi;
import org.ergoplatform.restapi.client.ErgoTransaction;
import org.ergoplatform.restapi.client.ErgoTransactionDataInput;
import org.ergoplatform.restapi.client.ErgoTransactionInput;
import org.ergoplatform.restapi.client.ErgoTransactionOutput;
import org.ergoplatform.restapi.client.InfoApi;
import org.ergoplatform.restapi.client.NodeInfo;
import org.ergoplatform.restapi.client.Transactions;
import org.ergoplatform.restapi.client.TransactionsApi;
import org.ergoplatform.restapi.client.UtxoApi;
import org.ergoplatform.restapi.client.WalletApi;
import org.ergoplatform.restapi.client.*;

import java.math.BigDecimal;
import java.util.ArrayList;
Expand Down Expand Up @@ -135,6 +124,29 @@ public List<InputBox> getUnspentBoxesFor(Address address, int offset, int limit)
List<OutputInfo> boxes = executeCall(explorerApi.getApiV1BoxesUnspentByaddressP1(address.toString(), offset, limit, "asc")).getItems();
return getInputBoxes(boxes);
}
@Override
public List<InputBox> getUnspentWalletBoxes(int minConfirmations, int minInclusionHeight) {
Preconditions.checkArgument(minConfirmations >= 0, "Minimum confirmations was less than 0");
Preconditions.checkArgument(minInclusionHeight >= 0, "Minimum inclusion height was less than 0");
List<WalletBox> walletBoxes = executeCall(getNodeWalletApi().walletBoxes(minConfirmations, minInclusionHeight));
return getFromWalletBoxes(walletBoxes, false);
}
@Override
public List<InputBox> getUnspentWalletBoxes() {
List<WalletBox> walletBoxes = executeCall(getNodeWalletApi().walletBoxes(0, 0));
return getFromWalletBoxes(walletBoxes, false);
}
@Override
public List<InputBox> getUnconfirmedUnspentWalletBoxes(int minInclusionHeight) {
Preconditions.checkArgument(minInclusionHeight >= 0, "Minimum inclusion height was less than 0");
List<WalletBox> walletBoxes = executeCall(getNodeWalletApi().walletBoxes(-1, minInclusionHeight));
return getFromWalletBoxes(walletBoxes, true);
}
@Override
public List<InputBox> getUnconfirmedUnspentWalletBoxes() {
List<WalletBox> walletBoxes = executeCall(getNodeWalletApi().walletBoxes(-1, 0));
return getFromWalletBoxes(walletBoxes, true);
}

@Override
public List<InputBox> getUnconfirmedUnspentBoxesFor(Address address, int offset, int limit) {
Expand Down Expand Up @@ -191,6 +203,24 @@ private List<InputBox> getInputBoxes(List<OutputInfo> boxes) {

return returnList;
}
private List<InputBox> getFromWalletBoxes(List<WalletBox> boxes, boolean withMemPool) {
ArrayList<InputBox> returnList = new ArrayList<>(boxes.size());

for (WalletBox box : boxes) {
String boxId = box.getBox().getBoxId();
InputBox boxInfo;
if(withMemPool) {
boxInfo = getBoxByIdWithMemPool(boxId);
}else{
boxInfo = getBoxById(boxId);
}
if (boxInfo != null) {
returnList.add(boxInfo);
}
}

return returnList;
}

protected <T> T executeCall(Call<T> apiCall) throws ErgoClientException {
try {
Expand Down