3using System.Collections.Generic;
4using System.Threading.Tasks;
23 private decimal amount = 0;
24 private bool transferred =
false;
25 private DateTime prevTP = DateTime.MinValue;
28 private readonly
bool addSecondaryTransactionObject;
37 this.addSecondaryTransactionObject = AddSecondaryTransactionObject;
48 if (this.wallet is
null)
50 this.
Uri.
State.Error(Uris.States.EDalerUriErrorType.ServiceUnavailable,
"Recipient wallet not found.",
false);
61 if (Converter is
null)
63 this.
Uri.
State.Error(Uris.States.EDalerUriErrorType.Forbidden,
"Recipient cannot receive eDaler in " +
this.Uri.Currency +
". No currency conversion service available.",
false);
70 if (this.quote is
null)
72 this.
Uri.
State.Error(Uris.States.EDalerUriErrorType.Forbidden,
"Recipient cannot receive eDaler in " +
this.Uri.Currency +
". Conversion not supported by service.",
false);
78 this.
Uri.
State.Error(Uris.States.EDalerUriErrorType.Forbidden,
"Recipient cannot receive eDaler in " +
this.Uri.Currency +
". Currency converter reports: " + ex.Message,
false);
82 this.amount *= this.quote.
Rate;
87 if (this.addSecondaryTransactionObject)
90 if (!(this.transaction is
null))
92 this.
Uri.
State.Error(Uris.States.EDalerUriErrorType.ResourceConstraint,
"eDaler transaction already processed.",
false);
97 this.transaction =
null;
110 if (this.addSecondaryTransactionObject &&
111 (!
string.IsNullOrEmpty(IoTGateway.Gateway.Domain) ||
113 this.Uri.State.Sender !=
"example.com" &&
114 this.Uri.State.Sender !=
"example2.com" &&
115 this.Uri.State.Sender !=
"example3.com")))
119 ObjectId = this.
Uri.
Id,
121 Processed = DateTime.UtcNow,
129 Uri = this.Uri.UriString
138 this.
Uri.
State.Error(Uris.States.EDalerUriErrorType.ResourceConstraint,
"eDaler transaction already processed.",
false);
145 this.
Uri.
State.Error(Uris.States.EDalerUriErrorType.ServiceUnavailable,
"eDaler transaction could not be processed due to internal failure.",
false);
153 DateTime BakTP = this.wallet.BalanceTimestamp;
154 decimal Bak = this.wallet.Balance;
155 bool RefAdded =
false;
161 TransactionId = this.
Uri.
Id,
162 Timestamp = DateTime.UtcNow,
163 Account = this.wallet.Account,
165 Change = this.amount,
166 Balance = this.wallet.Balance + this.amount,
167 Reserved = this.wallet.Reserved,
169 EncryptionPublicKey = this.Uri.EncryptionPublicKey
175 this.prevTP = this.wallet.BalanceTimestamp;
177 this.wallet.Balance += this.amount;
178 this.wallet.BalanceTimestamp = Ref.Timestamp;
182 this.transferred =
true;
188 this.
Uri.
State.Error(Uris.States.EDalerUriErrorType.ServiceUnavailable,
"eDaler transaction could not be processed due to internal failure.",
false);
190 this.wallet.Balance = Bak;
191 this.wallet.BalanceTimestamp = BakTP;
192 this.transferred =
false;
200 catch (Exception ex2)
233 string Xml = await this.
Uri.
EDaler.GetWalletBalanceXml(this.wallet.Account, Domain,
this.@event);
238 KeyValuePair<string, object>[] Tags =
new KeyValuePair<string, object>[]
241 new KeyValuePair<string, object>(
"Currency", this.
Uri.
Currency),
242 new KeyValuePair<string, object>(
"RefId", this.
Uri.
Id.ToString()),
243 new KeyValuePair<string, object>(
"Sender", this.
Uri.
State.Sender.Value),
246 new KeyValuePair<string, object>(
"Uri", this.
Uri.
UriString)
252 " eDaler received, and added to wallet.",
this.wallet.Account,
253 this.Uri.From.Address,
"eDalerReceived",
EventLevel.Major, Tags);
268 if (this.amount != 0 && this.transferred)
270 DateTime BakTP = this.wallet.BalanceTimestamp;
271 decimal Bak = this.wallet.Balance;
275 this.wallet.Balance -= this.amount;
277 if (this.wallet.BalanceTimestamp ==
this.@event.Timestamp)
278 this.wallet.BalanceTimestamp = this.prevTP;
282 this.transferred =
false;
288 this.wallet.Balance = Bak;
289 this.wallet.BalanceTimestamp = BakTP;
291 KeyValuePair<string, object>[] Tags =
new KeyValuePair<string, object>[]
294 new KeyValuePair<string, object>(
"Currency", this.
Uri.
Currency),
295 new KeyValuePair<string, object>(
"RefId", this.
Uri.
Id.ToString()),
296 new KeyValuePair<string, object>(
"Sender", this.
Uri.
State.Sender.Value),
299 new KeyValuePair<string, object>(
"Uri", this.
Uri.
UriString)
304 Log.
Error(
"Unable to rollback wallet change of " + this.amount.ToString() +
305 " for " +
this.wallet.Account +
". Error reported:\r\n\r\n" + ex.Message,
306 this.wallet.Account,
string.Empty,
"eDalerError", Tags);
310 if (!(this.@event is
null))
321 KeyValuePair<string, object>[] Tags =
new KeyValuePair<string, object>[]
324 new KeyValuePair<string, object>(
"Currency", this.
Uri.
Currency),
325 new KeyValuePair<string, object>(
"RefId", this.
Uri.
Id.ToString()),
326 new KeyValuePair<string, object>(
"Sender", this.
Uri.
State.Sender.Value),
329 new KeyValuePair<string, object>(
"Uri", this.
Uri.
UriString)
334 Log.
Error(
"Unable to rollback wallet event of " + this.amount.ToString() +
335 " for " +
this.wallet.Account +
". Error reported:\r\n\r\n" + ex.Message,
336 this.wallet.Account,
string.Empty,
"eDalerError", Tags);
341 if (!(this.transaction is
null))
344 this.transaction =
null;
Contains a pair of currencies, for currency conversion.
Static class managing the application event log. Applications and services log events on this static ...
static void Exception(Exception Exception, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, params KeyValuePair< string, object >[] Tags)
Logs an exception. Event type will be determined by the severity of the exception.
static void Error(string Message, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, string StackTrace, params KeyValuePair< string, object >[] Tags)
Logs an error event.
static void Notice(string Message, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, string StackTrace, params KeyValuePair< string, object >[] Tags)
Logs a notice event.
CaseInsensitiveString Subdomain
Subdomain name.
XmppServer Server
XMPP Server.
Contains information about one XMPP address.
CaseInsensitiveString Address
XMPP Address
static readonly XmppAddress Empty
Empty address.
Task< bool > SendMessage(string Type, string Id, string From, string To, string Language, string ContentXml)
Sends a Message stanza to a recipient.
CaseInsensitiveString Domain
Domain name.
Represents a case-insensitive string.
string Value
String-representation of the case-insensitive string. (Representation is case sensitive....
static bool IsNullOrEmpty(CaseInsensitiveString value)
Indicates whether the specified string is null or an CaseInsensitiveString.Empty string.
Static interface for database persistence. In order to work, a database provider has to be assigned t...
static async Task Update(object Object)
Updates an object in the database.
static async Task Delete(object Object)
Deletes an object in the database.
static async Task Insert(object Object)
Inserts an object into the default collection of the database.
static Task< object > TryLoadObject(string CollectionName, object ObjectId)
Tries to load an object given its Object ID ObjectId and its collection name CollectionName .
An attempt to insert a key was done, but the key was already there.
Static class that dynamically manages types and interfaces available in the runtime environment.
Represents a named semaphore, i.e. an object, identified by a name, that allows single concurrent wri...
Static class of application-wide semaphores that can be used to order access to editable objects.
static async Task< Semaphore > BeginWrite(string Key)
Waits until the semaphore identified by Key is ready for writing. Each call to BeginWrite must be fo...
Transaction()
Abstract base class for transactions.
Abstract base class for eDaler transactions.
async Task< Wallet > GetWallet(XmppAddress For, EntityType ForType)
Gets the wallet of an entity in an eDaler transaction.
Handles the local recipient of eDaler.
override async Task< bool > DoPrepare()
Performs actual preparation.
override async Task< bool > DoRollback()
Performs actual rollback.
LocalRecipient(EDalerUri Uri, bool AddSecondaryTransactionObject)
Handles the local recipient of eDaler.
override async Task< bool > DoCommit()
Performs actual commit.
override async Task< bool > DoExecute()
Performs actual execution.
Handles the local sender of eDaler.
Abstract base class for eDaler URIs
EntityType ToType
Type of recipient.
string UriString
Original URI String.
EntityType FromType
Type of sender
EDalerUriState State
URI State object.
EDalerComponent EDaler
eDaler component reference
DateTime Created
When URI was created
decimal TotalAmount
Total amount: Amount+AmountExtra
byte[] EncryptedMessage
Encrypted message for recipient. If EncryptionPublicKey is null, the message is just UTF-8 encoded.
Retains the current balance of an account.
Interface for currency conversion quotes.
decimal Rate
Exchange rate.
Interface for currency converter services
Task< ICurrencyConverterQuote > GetCurrencyConversionQuote(CaseInsensitiveString FromCurrency, CaseInsensitiveString ToCurrency)
Gets a Currency Exchange Rate from one currency to another.