Я работаю с приложением биткойн-кошелька, и пользовательский интерфейс выглядит,
Когда я выбираю адрес из выпадающего меню и нажимаю кнопки balance
или transaction
, они должны открываться на новой странице и отображать соответствующую информацию.
Когда я получаю BTC в определенном кошельке, он должен обновить balance
кошелек на активной странице. Однако это не работает так, как ожидалось, и у меня, как всегда, только 0 BTC. Раньше это был только один кошелек (без поддержки нескольких кошельков), и на этот раз тот же код работал нормально.
Класс, который настраивает кошелек,
public class WalletManager {
public static WalletAppKit bitcoin;
private static WalletManager walletManager;
// public static NetworkParameters networkParameters = MainNetParams.get();
public static NetworkParameters networkParameters = TestNet3Params.get();
public static final String APP_NAME = "WalletTemplate";
public static final String WALLET_FILE_NAME = APP_NAME.replaceAll("[^a-zA-Z0-9.-]", "_")
+ networkParameters.getPaymentProtocolId();
private static final Logger logger = LoggerFactory.getLogger(WalletManager.class);
private WalletModel model = new WalletModel();
private List<WalletSetupCompletedListener> setupCompletedListeners = Collections.synchronizedList(new LinkedList<>());
public static WalletManager setupWallet(final String walletName) {
logger.info("Setup Wallet");
walletManager = new WalletManager();
walletManager.setupWalletKit(walletName);
try {
if (walletManager.bitcoin.isChainFileLocked()) {
return walletManager;
}
} catch (IOException e) {
e.printStackTrace();
return walletManager;
}
walletManager.bitcoin.startAsync();
return walletManager;
}
private WalletManager() {}
protected File getWalletDirectory(final String walletId) {
File dir = new File(walletId);
if (!dir.exists()) {
dir.mkdir();
}
return dir;
}
private void setupWalletKit(final String walletId) {
File directory = getWalletDirectory(walletId);
// if the seed is not null, that means we are restoring from the backup
bitcoin = new WalletAppKit(networkParameters, directory, WALLET_FILE_NAME) {
@Override
protected void onSetupCompleted() {
// Don't make the user wait for confirmations
// they're sending their own money anyway!!
bitcoin.wallet().allowSpendingUnconfirmedTransactions();
Wallet wallet = bitcoin.wallet();
model.setWallet(wallet);
setupCompletedListeners.forEach(listener -> listener.onSetupCompleted(wallet));
}
};
// Now configure and start the appkit. This will take a second or two - we could show a temporary splash screen
// or progress widget to keep the user engaged whilst we initialise, but we don't.
if (networkParameters == RegTestParams.get()) {
bitcoin.connectToLocalHost(); // You should run a regtest mode bitcoind locally.
} else if (networkParameters == TestNet3Params.get()) {
bitcoin.useTor();
}
bitcoin.setDownloadListener(model.getSyncProgressUpdater())
.setBlockingStartup(false)
.setUserAgent(APP_NAME, "1.0");
}
public WalletAppKit getWalletAppKit() {
return bitcoin;
}
public WalletModel getModel() {
return model;
}
public void addWalletSetupCompletedListener(final WalletSetupCompletedListener listener) {
setupCompletedListeners.add(listener);
}
}
Класс, отвечающий за обновление кошелька, представлен ниже,
public class WalletModel {
private List<Transaction> transactions = Collections.synchronizedList(new ArrayList<>());
private ProgressBarUpdater syncProgressUpdater = new ProgressBarUpdater();
private static double SYNCHRONISATION_FINISHED = 1.0;
private double syncProgress = -1.0;
private Coin balance = Coin.ZERO;
private Address address;
private String transaction;
private int UserId;
public int getUserId() {
return UserId;
}
public void setUserId(int userId) {
this.UserId = userId;
}
public String getTransaction() {
return transaction;
}
public void setTransaction(String transaction) {
this.transaction = transaction;
}
private List<String> history = new ArrayList<>();
public List<String> getHistory() {
for (Transaction t : transactions) {
history.add(addTransactionHistory(t));
}
return history;
}
public WalletModel() {
}
public WalletModel(Wallet wallet) {
setWallet(wallet);
}
private void update(Wallet wallet) {
this.balance = wallet.getBalance();
this.address = wallet.currentReceiveAddress();
transactions.addAll(wallet.getRecentTransactions(100,
true));
this.transaction = Objects.isNull(transactions) || transactions.isEmpty()
? "" : String.valueOf(transactions.get(0));
}
public boolean setWallet(Wallet wallet) {
try {
wallet.addChangeEventListener(new WalletChangeEventListener() {
@Override
public void onWalletChanged(Wallet wallet) {
update(wallet);
}
});
update(wallet);
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
private class ProgressBarUpdater extends DownloadProgressTracker {
@Override
protected void progress(double percentage, int blocksSoFar, Date date) {
super.progress(percentage, blocksSoFar, date);
syncProgress = percentage / 100.0;
}
@Override
protected void doneDownload() {
super.doneDownload();
syncProgress = SYNCHRONISATION_FINISHED;
}
}
public boolean isSyncFinished() {
return syncProgress == SYNCHRONISATION_FINISHED;
}
public Address getAddress() {
return address;
}
/**
* @param
* @return the Satoshi coin based on the wallet balance
*/
public Coin getBalance() {
return balance;
}
/**
* @return get the BTC amount as float from the wallet balance
*/
public float getBalanceFloatFormat() {
float bal = (float) balance.getValue();
float fac = (float) Math.pow(10, 8);
float result = bal / fac;
return result;
}
/**
* @param transaction take the wallet transaction as an input
* @return the trasaction info of the wallet
*/
private String addTransactionHistory(Transaction transaction) {
if (Objects.isNull(transaction)) {
return "No transaction";
}
Coin value = transaction.getValue(WalletManager.bitcoin.wallet());
if (value.isPositive()) {
String message = "Incoming payment of " + MonetaryFormat.BTC.format(value);
return message;
} else if (value.isNegative()) {
Address address = transaction.getOutput(0).getAddressFromP2PKHScript(networkParameters);
String message = "Outbound payment to " + address + " worth of " +
(MonetaryFormat.BTC.format(value)).toString().replaceAll("-", "");
return message;
}
String message = "Payment with id " + transaction.getHash();
return message;
}
public double getSyncProgress() {
return syncProgress;
}
public ProgressBarUpdater getSyncProgressUpdater() {
return syncProgressUpdater;
}
public List<Transaction> getTransactions() {
return transactions;
}
}
public interface WalletSetupCompletedListener {
void onSetupCompleted(Wallet wallet);
}
Как разработать код для поддержки нескольких кошельков? Я могу предоставить вырезанный код, если потребуется.
Удалите блок для else, если вы использовали useTor(), он вообще не нужен
Эндрю Чоу
Марч
Арефе
Марч