Skip to content

Instantly share code, notes, and snippets.

@Kikimora
Created September 20, 2017 15:47
Show Gist options
  • Save Kikimora/3b4d503dac7238f675c6d20a0644a135 to your computer and use it in GitHub Desktop.
Save Kikimora/3b4d503dac7238f675c6d20a0644a135 to your computer and use it in GitHub Desktop.
public enum Network { Bitcoin, Ethereum }
public interface IWeakListener
{
void OnMessage(Notification notification);
}
public class SendModel : DataContext, IWeakListener
{
public SendModel()
{
SendCommand = new AsyncCommand(Send, _ => !_.IsRunning);
PropertyChanged += ValidateCalculatedProperties;
//Subscribe to events which comes not from UI but from our model.
//Subscriptions are implemented as weak references.
WalletContext.MessageHub.Subscribe("Bitcoin.AvailableFunds", this);
WalletContext.MessageHub.Subscribe("ethereum.AvailableFunds", this);
}
void IWeakListener.OnMessage(Notification notification)
{
RaisePropertyChanged(nameof(AvailableFunds));
}
decimal _amount;
public decimal Amount
{
get => _amount;
set
{
//Amount cannot be less than 0
Validator.CheckProperty(value).MoreOrEqThan(0);
if (value == _amount)
{
_amount = value;
RaisePropertyChanged(nameof(Amount));
OnTotalTransactionAmountChanged();
}
}
}
//Only valid for bitcoin
decimal _fee;
public decimal Fee
{
get => Network == Network.Bitcoin ? _fee : 0;
set
{
//Fee cannot be less than 0
Validator.CheckProperty(value).MoreOrEqThan(0).LessThan();
if (value != _fee)
{
_fee = value;
RaisePropertyChanged(nameof(Fee));
OnTotalTransactionAmountChanged();
}
}
}
public decimal TotalTransactionAmount
{
get
{
return Amount + Fee;
}
}
string _recipient;
public string Recipient
{
get => _recipient;
set
{
var checker = Validator.CheckProperty(value).NotEmpty();
if (Network == Network.Bitcoin)
{
checker.Convert(BitcoinAddress.Parse);
}
else if (Network == Network.Ethereum)
{
checker.Convert(EthereumAddress.Parse);
}
if (value != _recipient)
{
_recipient = value;
RaisePropertyChanged(nameof(Recipient));
}
}
}
Network _network;
public Network Network
{
get => _network;
set
{
if (value != _network)
{
_network = value;
RaisePropertyChanged(nameof(Network));
RaisePropertyChanged(nameof(Fee));
OnAvailableFundsChanged();
Validate();
}
}
}
public decimal AvailableFunds
{
get
{
if (Network == Network.Bitcoin)
{
return WalletContext.User.Bitcoin.AvailableFunds;
}
else if (Network == Network.Ethereum)
{
return WalletContext.User.Ethereum.AvailableFunds;
}
else throw new NotImplementedException();
}
}
private void OnTotalTransactionAmountChanged()
{
ValidateTotalAmount();
RaisePropertyChanged(nameof(TotalTransactionAmount));
}
private void ValidateTotalAmount()
{
Validator.Check(TotalTransactionAmount, nameof(TotalTransactionAmount))
.LessThan(AvailableFunds);
}
private void OnAvailableFundsChanged()
{
RaisePropertyChanged(nameof(AvailableFunds));
//TotalTransactionAmount depends on AvailableFunds;
OnTotalTransactionAmountChanged();
}
private async Task Send(object arg, CancellationToken token)
{
//Check what network and create appropriate complex data structures based on user entered primitive data
if (Network == Network.Bitcoin)
{
var address = BitcoinAddress.Parse(Recipient);
var sender = WalletContext.User.Bitcoin.Address;
await WalletContext.SendService.Send(sender, address, Amount, Fee);
}
else if (Network == Network.Ethereum)
{
var address = EthereumAddress.Parse(Recipient);
var sender = WalletContext.User.Ethereum.Address;
await WalletContext.SendService.Send(sender, address, Amount, Fee);
}
else throw new NotImplementedException();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment