-
Notifications
You must be signed in to change notification settings - Fork 89
Add signal when transaction found in wallet, and filtering on wallet #102
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -46,6 +46,11 @@ public class WalletRPCController : FeatureController | |
| /// <summary>Wallet related configuration.</summary> | ||
| private readonly WalletSettings walletSettings; | ||
|
|
||
| /// <summary> | ||
| /// The wallet name set by selectwallet method. This is static since the controller is a stateless type. This value should probably be cached by an injected service in the future. | ||
| /// </summary> | ||
| private static string CurrentWalletName; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should fix this now, it will be a fast fix maybe use as a hack put the field on the WallletManager just to avoid it being static?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah I realize this is on RPC, it less crucial for me so this is fine (if it does not break tests)
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Doesn't break anything, and it is to give a custom support for multi-wallet in the RPC. It's a fairly important extra RPC method for anyone who relies on the RPC and have multiple wallets, but I don't think there are many that will ever use this. It is very useful when debugging and working with multiple wallets at the same time (normal wallet and special wallets). |
||
|
|
||
| public WalletRPCController( | ||
| IBlockStore blockStore, | ||
| IBroadcasterManager broadcasterManager, | ||
|
|
@@ -70,6 +75,14 @@ public WalletRPCController( | |
| this.walletTransactionHandler = walletTransactionHandler; | ||
| } | ||
|
|
||
| [ActionName("setwallet")] | ||
| [ActionDescription("Selects the active wallet on RPC based on the name of the wallet supplied.")] | ||
| public bool SetWallet(string walletname) | ||
| { | ||
| WalletRPCController.CurrentWalletName = walletname; | ||
| return true; | ||
| } | ||
|
|
||
| [ActionName("walletpassphrase")] | ||
| [ActionDescription("Stores the wallet decryption key in memory for the indicated number of seconds. Issuing the walletpassphrase command while the wallet is already unlocked will set a new unlock time that overrides the old one.")] | ||
| public bool UnlockWallet(string passphrase, int timeout) | ||
|
|
@@ -419,10 +432,22 @@ public GetTransactionModel GetTransaction(string txid) | |
| } | ||
| } | ||
|
|
||
| // Get the ColdStaking script template if available. | ||
| Dictionary<string, ScriptTemplate> templates = this.walletManager.GetValidStakingTemplates(); | ||
| ScriptTemplate coldStakingTemplate = templates.ContainsKey("ColdStaking") ? templates["ColdStaking"] : null; | ||
|
|
||
| // Receive transactions details. | ||
| foreach (TransactionData trxInWallet in receivedTransactions) | ||
| { | ||
| // Skip the details if the script pub key is cold staking. | ||
| // TODO: Verify if we actually need this any longer, after changing the internals to recognice account type! | ||
| if (coldStakingTemplate != null && coldStakingTemplate.CheckScriptPubKey(trxInWallet.ScriptPubKey)) | ||
| { | ||
| continue; | ||
| } | ||
|
|
||
| GetTransactionDetailsCategoryModel category; | ||
|
|
||
| if (isGenerated) | ||
| { | ||
| category = model.Confirmations > this.FullNode.Network.Consensus.CoinbaseMaturity ? GetTransactionDetailsCategoryModel.Generate : GetTransactionDetailsCategoryModel.Immature; | ||
|
|
@@ -792,6 +817,43 @@ public async Task<uint256> SendManyAsync(string fromAccount, string addressesJso | |
| } | ||
| } | ||
|
|
||
| [ActionName("getwalletinfo")] | ||
| [ActionDescription("Provides information about the wallet.")] | ||
| public GetWalletInfoModel GetWalletInfo() | ||
| { | ||
| var accountReference = this.GetWalletAccountReference(); | ||
| var account = this.walletManager.GetAccounts(accountReference.WalletName) | ||
| .Where(i => i.Name.Equals(accountReference.AccountName)) | ||
| .Single(); | ||
|
|
||
| (Money confirmedAmount, Money unconfirmedAmount) = account.GetBalances(account.IsNormalAccount()); | ||
|
|
||
| var balance = Money.Coins(GetBalance(string.Empty)); | ||
| var immature = Money.Coins(balance.ToDecimal(MoneyUnit.BTC) - GetBalance(string.Empty, (int)this.FullNode.Network.Consensus.CoinbaseMaturity)); // Balance - Balance(AtHeight) | ||
|
|
||
| var model = new GetWalletInfoModel | ||
| { | ||
| Balance = balance, | ||
| WalletName = accountReference.WalletName + ".wallet.json", | ||
| WalletVersion = 1, | ||
| UnConfirmedBalance = unconfirmedAmount, | ||
| ImmatureBalance = immature | ||
| }; | ||
|
|
||
| return model; | ||
| } | ||
|
|
||
| private int GetConformationCount(TransactionData transaction) | ||
| { | ||
| if (transaction.BlockHeight.HasValue) | ||
| { | ||
| var blockCount = this.ConsensusManager?.Tip.Height ?? -1; // TODO: This is available in FullNodeController, should refactor and reuse the logic. | ||
| return blockCount - transaction.BlockHeight.Value; | ||
| } | ||
|
|
||
| return -1; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Gets the first account from the "default" wallet if it specified, | ||
| /// otherwise returns the first available account in the existing wallets. | ||
|
|
@@ -801,16 +863,27 @@ private WalletAccountReference GetWalletAccountReference() | |
| { | ||
| string walletName = null; | ||
|
|
||
| if (this.walletSettings.IsDefaultWalletEnabled()) | ||
| walletName = this.walletManager.GetWalletsNames().FirstOrDefault(w => w == this.walletSettings.DefaultWalletName); | ||
| // If the global override is null or empty. | ||
| if (string.IsNullOrWhiteSpace(WalletRPCController.CurrentWalletName)) | ||
| { | ||
| if (this.walletSettings.IsDefaultWalletEnabled()) | ||
| walletName = this.walletManager.GetWalletsNames().FirstOrDefault(w => w == this.walletSettings.DefaultWalletName); | ||
| else | ||
| { | ||
| //TODO: Support multi wallet like core by mapping passed RPC credentials to a wallet/account | ||
| walletName = this.walletManager.GetWalletsNames().FirstOrDefault(); | ||
| } | ||
| } | ||
| else | ||
| { | ||
| //TODO: Support multi wallet like core by mapping passed RPC credentials to a wallet/account | ||
| walletName = this.walletManager.GetWalletsNames().FirstOrDefault(); | ||
| // Read from class instance the wallet name. | ||
| walletName = WalletRPCController.CurrentWalletName; | ||
| } | ||
|
|
||
| if (walletName == null) | ||
| { | ||
| throw new RPCServerException(RPCErrorCode.RPC_INVALID_REQUEST, "No wallet found"); | ||
| } | ||
|
|
||
| HdAccount account = this.walletManager.GetAccounts(walletName).First(); | ||
| return new WalletAccountReference(walletName, account.Name); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| using System; | ||
| using System.Collections.Generic; | ||
| using System.Text; | ||
| using Blockcore.EventBus; | ||
| using NBitcoin; | ||
|
|
||
| namespace Blockcore.Features.Wallet.Events | ||
| { | ||
| /// <summary> | ||
| /// Event that is executed when a transaction is found in the wallet. | ||
| /// </summary> | ||
| /// <seealso cref="Blockcore.EventBus.EventBase" /> | ||
| public class TransactionFound : EventBase | ||
| { | ||
| public Transaction FoundTransaction { get; } | ||
|
|
||
| public TransactionFound(Transaction foundTransaction) | ||
| { | ||
| this.FoundTransaction = foundTransaction; | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| using Blockcore.Utilities.JsonConverters; | ||
| using NBitcoin; | ||
| using Newtonsoft.Json; | ||
|
|
||
| namespace Blockcore.Features.Wallet.Models | ||
| { | ||
| /// <summary>Model for RPC method getwalletinfo.</summary> | ||
| public class GetWalletInfoModel | ||
| { | ||
| [JsonProperty("walletname")] | ||
| public string WalletName { get; set; } | ||
|
|
||
| [JsonProperty("walletversion")] | ||
| public int WalletVersion { get; set; } | ||
|
|
||
| [JsonProperty("balance")] | ||
| [JsonConverter(typeof(MoneyInCoinsJsonConverter))] | ||
| public Money Balance { get; set; } | ||
|
|
||
| [JsonProperty("unconfirmed_balance")] | ||
| [JsonConverter(typeof(MoneyInCoinsJsonConverter))] | ||
| public Money UnConfirmedBalance { get; set; } | ||
|
|
||
| [JsonProperty("immature_balance")] | ||
| [JsonConverter(typeof(MoneyInCoinsJsonConverter))] | ||
| public Money ImmatureBalance { get; set; } | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why remove the -1?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It previously synced just minus 1 block, now it syncs minus 1 day, see 3rd line from above this line.