Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
TokenModel.cs
7using LegalLab.Tabs;
8using NeuroFeatures;
11using System;
12using System.Collections.Generic;
13using System.IO;
14using System.Threading.Tasks;
15using System.Windows;
16using System.Windows.Controls;
17using System.Windows.Media.Imaging;
18using System.Xml;
21using Waher.Events;
23using Waher.Script;
25
27{
32 {
33 private readonly DesignModel designModel;
34 private readonly NeuroFeaturesClient client;
35 private readonly Token token;
36 private readonly string language;
37 private NoteCommand[] noteCommands;
38 private TokenDetail[] details;
39 private BitmapImage glyph;
40 private string currentState = null;
41 private Variables currentVariables = null;
42
43 private readonly Command viewPresentReport;
44 private readonly Command viewHistoryReport;
45 private readonly Command viewStateDiagramReport;
46 private readonly Command viewProfilingReport;
47 private readonly ParametrizedCommand executeNoteCommand;
48
56 private TokenModel(NeuroFeaturesClient Client, Token Token, string Language, DesignModel DesignModel)
57 {
58 this.designModel = DesignModel;
59 this.client = Client;
60 this.token = Token;
61 this.language = Language;
62
63 this.viewPresentReport = new Command(this.CanExecuteViewStateMachineReport, this.ExecuteViewPresentReport);
64 this.viewHistoryReport = new Command(this.CanExecuteViewStateMachineReport, this.ExecuteViewHistoryReport);
65 this.viewStateDiagramReport = new Command(this.CanExecuteViewStateMachineReport, this.ExecuteViewStateDiagramReport);
66 this.viewProfilingReport = new Command(this.CanExecuteViewStateMachineReport, this.ExecuteViewProfilingReport);
67 this.executeNoteCommand = new ParametrizedCommand(this.CanExecuteNoteCommand, this.ExecuteNoteCommand);
68 }
69
73 public Token Token => this.token;
74
78 public NoteCommand[] NoteCommands => this.noteCommands;
79
83 public Command ViewPresentReport => this.viewPresentReport;
84
88 public Command ViewHistoryReport => this.viewHistoryReport;
89
93 public Command ViewStateDiagramReport => this.viewStateDiagramReport;
94
98 public Command ViewProfilingReport => this.viewProfilingReport;
99
103 public ParametrizedCommand NoteCommand => this.executeNoteCommand;
104
105 public static async Task<TokenModel> CreateAsync(NeuroFeaturesClient Client, Token Token, string Language, DesignModel DesignModel)
106 {
107 TokenModel Result = new(Client, Token, Language, DesignModel);
108
109 Result.noteCommands = await Result.token.GetNoteCommands();
110
111 List<TokenDetail> Details = new()
112 {
113 new TokenDetail("Token ID", Result.token.TokenId, false),
114 new TokenDetail("Token ID Method", Result.token.TokenIdMethod, false),
115 new TokenDetail("Short ID", Result.token.ShortId, false),
116 new TokenDetail("Ordinal", Result.token.Ordinal, false),
117 new TokenDetail("Batch Size", Result.token.BatchSize, false),
118 new TokenDetail("Created", Result.token.Created, false),
119 new TokenDetail("Updated", Result.token.Updated, false),
120 new TokenDetail("Value", Result.token.Value, false),
121 new TokenDetail("Currency", Result.token.Currency, false),
122 new TokenDetail("Expires", Result.token.Expires, false),
123 new TokenDetail("Archivig time (Required, false)", Result.token.ArchiveRequired, false),
124 new TokenDetail("Archivig time (Optional, false)", Result.token.ArchiveOptional, false),
125 new TokenDetail("Signature Timestamp", Result.token.SignatureTimestamp, false),
126 new TokenDetail("Signature", Convert.ToBase64String(Result.token.Signature), false),
127 new TokenDetail("Definition Schema Digest", Convert.ToBase64String(Result.token.DefinitionSchemaDigest), false),
128 new TokenDetail("Definition Schema Hash Function", Result.token.DefinitionSchemaHashFunction, false),
129 new TokenDetail("Creator Can Destroy", Result.token.CreatorCanDestroy, false),
130 new TokenDetail("Owner Can Destroy Batch", Result.token.OwnerCanDestroyBatch, false),
131 new TokenDetail("Owner Can Destroy Individual", Result.token.OwnerCanDestroyIndividual, false),
132 new TokenDetail("Certifier Can Destroy", Result.token.CertifierCanDestroy, false),
133 new TokenDetail("Friendly Name", Result.token.FriendlyName, false),
134 new TokenDetail("Category", Result.token.Category, false),
135 new TokenDetail("Description", await MarkdownToXaml(Result.token.Description), false),
136 new TokenDetail("Glyph", Convert.ToBase64String(Result.token.Glyph), false),
137 new TokenDetail("Glyph Content Type", Result.token.GlyphContentType, false),
138 new TokenDetail("Glyph Width", Result.token.GlyphWidth, false),
139 new TokenDetail("Glyph Height", Result.token.GlyphHeight, false),
140 new TokenDetail("Visibility", Result.token.Visibility, false),
141 new TokenDetail("Creator", Result.token.Creator, false),
142 new TokenDetail("CreatorJid", Result.token.CreatorJid, false),
143 new TokenDetail("Owner", Result.token.Owner, false),
144 new TokenDetail("OwnerJid", Result.token.OwnerJid, false),
145 new TokenDetail("TrustProvider", Result.token.TrustProvider, false),
146 new TokenDetail("TrustProviderJid", Result.token.TrustProviderJid, false),
147 new TokenDetail("Reference", Result.token.Reference, false),
148 new TokenDetail("Definition", Result.token.Definition, false),
149 new TokenDetail("DefinitionNamespace", Result.token.DefinitionNamespace, false),
150 new TokenDetail("CreationContract", Result.token.CreationContract, false),
151 new TokenDetail("OwnershipContract", Result.token.OwnershipContract, false)
152 };
153
154 foreach (string s in Result.token.Witness)
155 Details.Add(new TokenDetail("Witness", s, false));
156
157 foreach (string s in Result.token.CertifierJids)
158 Details.Add(new TokenDetail("CertifierJid", s, false));
159
160 foreach (string s in Result.token.CertifierJids)
161 Details.Add(new TokenDetail("CertifierJid", s, false));
162
163 foreach (string s in Result.token.Certifier)
164 Details.Add(new TokenDetail("Certifier", s, false));
165
166 foreach (string s in Result.token.Valuator)
167 Details.Add(new TokenDetail("Valuator", s, false));
168
169 foreach (string s in Result.token.Assessor)
170 Details.Add(new TokenDetail("Assessor", s, false));
171
172 foreach (TokenTag Tag in Result.token.Tags)
173 Details.Add(new TokenDetail(Tag.Name, Tag.Value, false));
174
175 if (Result.token.HasStateMachine)
176 {
177 Details.Add(new TokenDetail("State-Machine Present State", new Button()
178 {
179 Command = Result.viewPresentReport,
180 Content = "Present State...",
181 Margin = new Thickness(10, 2, 10, 2),
182 MinWidth = 150
183 }, false));
184
185 Details.Add(new TokenDetail("State-Machine History", new Button()
186 {
187 Command = Result.viewHistoryReport,
188 Content = "History...",
189 Margin = new Thickness(10, 2, 10, 2),
190 MinWidth = 150
191 }, false));
192
193 Details.Add(new TokenDetail("State-Machine State Diagram", new Button()
194 {
195 Command = Result.viewStateDiagramReport,
196 Content = "State Diagram...",
197 Margin = new Thickness(10, 2, 10, 2),
198 MinWidth = 150
199 }, false));
200
201 Details.Add(new TokenDetail("State-Machine Profiling", new Button()
202 {
203 Command = Result.viewProfilingReport,
204 Content = "Profiling...",
205 Margin = new Thickness(10, 2, 10, 2),
206 MinWidth = 150
207 }, false));
208
209 await Result.AddNoteCommands(Details);
210 }
211
212 Result.details = Details.ToArray();
213
214 return Result;
215 }
216
220 public async Task UpdateNoteCommands()
221 {
222 List<TokenDetail> Details = new();
223
224 foreach (TokenDetail Detail in this.details)
225 {
226 if (!Detail.NoteCommand)
227 Details.Add(Detail);
228 }
229
230 await this.AddNoteCommands(Details);
231
233 {
234 this.Details = Details.ToArray();
235 return Task.CompletedTask;
236 });
237 }
238
239 public async Task<KeyValuePair<NoteCommand, int>[]> GetContextSpecificNoteCommands(bool IsOwner)
240 {
241 Variables v = new()
242 {
243 ["State"] = this.currentState,
244 ["<State>"] = this.currentState
245 };
246 int i, c = this.noteCommands?.Length ?? 0;
247 List<KeyValuePair<NoteCommand, int>> Result = new();
248
249 this.currentVariables?.CopyTo(v);
250
251 for (i = 0; i < c; i++)
252 {
253 NoteCommand NoteCommand = this.noteCommands[i];
254
255 if (IsOwner)
256 {
258 continue;
259 }
260 else
261 {
263 continue;
264 }
265
267 {
268 try
269 {
271 if (Obj is not bool b || !b)
272 continue;
273 }
274 catch (Exception ex)
275 {
276 Log.Exception(ex);
277 continue;
278 }
279 }
280
281 Result.Add(new KeyValuePair<NoteCommand, int>(NoteCommand, i));
282 }
283
284 return Result.ToArray();
285 }
286
287 private async Task AddNoteCommands(List<TokenDetail> Details)
288 {
289 KeyValuePair<NoteCommand, int>[] Commands = await this.GetContextSpecificNoteCommands(true);
290
291 foreach (KeyValuePair<NoteCommand, int> P in Commands)
292 {
293 NoteCommand NoteCommand = P.Key;
294 int i = P.Value;
295
296 Details.Add(new TokenDetail(NoteCommand.ToolTip?.Find(this.language), new Button()
297 {
298 Command = this.executeNoteCommand,
299 CommandParameter = i,
300 Content = NoteCommand.Title?.Find(this.language),
301 Margin = new Thickness(10, 2, 10, 2),
302 MinWidth = 150
303 }, true));
304 }
305 }
306
307 private static async Task<object> MarkdownToXaml(string Markdown)
308 {
309 MarkdownDocument Doc = await MarkdownDocument.CreateAsync(Markdown);
310 string Xaml = await Doc.GenerateXAML();
311 return Xaml.ParseSimple();
312 }
313
317 public BitmapImage Glyph
318 {
319 get
320 {
321 if (this.glyph is null && this.token.Glyph is not null)
322 {
323 BitmapImage Result = new();
324 Result.BeginInit();
325 Result.CreateOptions = BitmapCreateOptions.None;
326 Result.CacheOption = BitmapCacheOption.Default;
327 Result.StreamSource = new MemoryStream(this.token.Glyph);
328 Result.EndInit();
329
330 this.glyph = Result;
331 }
332
333 return this.glyph;
334 }
335 }
336
340 public string FriendlyName => this.token.FriendlyName;
341
345 public string Category => this.token.Category;
346
350 public string Description => this.token.Description;
351
355 public string TokenId => this.token.TokenId;
356
360 public DateTime Expires => this.token.Expires;
361
365 public decimal Value => this.token.Value;
366
370 public string Currency => this.token.Currency;
371
375 public DateTime Updated => this.token.Updated;
376
380 public string Creator => this.token.Creator;
381
385 public ContractVisibility Visibility => this.token.Visibility;
386
391 {
392 get => this.details;
393 set
394 {
395 this.details = value;
396 this.RaisePropertyChanged(nameof(this.Details));
397 }
398 }
399
400 private bool CanExecuteViewStateMachineReport()
401 {
402 return this.token.HasStateMachine;
403 }
404
405 private async Task ExecuteViewPresentReport()
406 {
407 if (!string.IsNullOrEmpty(this.TokenId))
408 await AddReport(new TokenPresentReport(this.client, this.TokenId));
409 }
410
411 private async Task ExecuteViewHistoryReport()
412 {
413 if (!string.IsNullOrEmpty(this.TokenId))
414 await AddReport(new TokenHistoryReport(this.client, this.TokenId));
415 }
416
417 private async Task ExecuteViewStateDiagramReport()
418 {
419 if (!string.IsNullOrEmpty(this.TokenId))
420 await AddReport(new TokenStateDiagramReport(this.client, this.TokenId));
421 }
422
423 private async Task ExecuteViewProfilingReport()
424 {
425 if (!string.IsNullOrEmpty(this.TokenId))
426 await AddReport(new TokenProfilingReport(this.client, this.TokenId));
427 }
428
429 private static async Task AddReport(TokenReport Report)
430 {
432 try
433 {
434 ReportTab ReportTab = new(Report);
435 string Title = await Report.GetTitle();
436
437 await Report.GenerateReport(ReportTab);
438
439 TabItem Tab = MainWindow.NewTab(Title);
440 Tab.Content = ReportTab;
441
442 MainWindow.currentInstance.TabControl.Items.Add(Tab);
443 MainWindow.currentInstance.TabControl.SelectedItem = Tab;
444 }
445 catch (Exception ex)
446 {
447 MainWindow.ErrorBox(ex.Message);
448 }
449 finally
450 {
452 }
453 }
454
455 private bool CanExecuteNoteCommand(object Parameter)
456 {
457 return
458 this.token.HasStateMachine &&
459 this.noteCommands is not null &&
460 (Parameter is null ||
461 (Parameter is int i &&
462 i >= 0 &&
463 i < this.noteCommands.Length));
464 }
465
466 private async void ExecuteNoteCommand(object Parameter)
467 {
468 try
469 {
470 if (this.token.HasStateMachine &&
471 this.noteCommands is not null &&
472 Parameter is int i &&
473 i >= 0 &&
474 i < this.noteCommands.Length)
475 {
476 NoteCommand Command = this.noteCommands[i];
477 Variables NoteParameters;
478 string Msg;
479
480 try
481 {
482 if (Command.HasParameters)
483 {
484 ContractParametersModel Model = new(Command.Parameters, null, this.language, this.designModel);
485 ParametersDialog Dialog = new(Command.Title.Find(this.language), Model)
486 {
487 Owner = MainWindow.currentInstance
488 };
489
490 await Model.Start();
491 Control First = await Model.PopulateParameters(null, Dialog.ParametersPanel, null, null);
492
493 if (First is not null)
494 {
495 First.Focus();
496
497 bool? Result = Dialog.ShowDialog();
498 if (!Result.HasValue || !Result.Value)
499 return;
500
501 NoteParameters = await Model.ValidateParameters()
502 ?? throw new Exception("Invalid parameters.");
503 }
504 else
505 NoteParameters = new Variables();
506 }
507 else
508 NoteParameters = new Variables();
509
510 Msg = Command.Confirmation?.Find(this.language);
511 if (!string.IsNullOrEmpty(Msg))
512 {
513 MessageBoxResult Confirmation = await MainWindow.MessageBox(Msg, "Confirmation",
514 MessageBoxButton.YesNoCancel, MessageBoxImage.Question);
515
516 if (Confirmation != MessageBoxResult.Yes)
517 return;
518 }
519
520 Waher.Script.Expression Exp = Command.ParsedNoteGenerationScript
521 ?? (string.IsNullOrEmpty(Command.NoteGenerationScript) ?
522 throw new Exception("Missing note script.")
523 : new Waher.Script.Expression(Command.NoteGenerationScript));
524
525 if (!Exp.CheckExpressionSafe(out ScriptNode Prohibited))
526 throw new Exception("Command blocked. Unsafe portion of script: " + Prohibited.SubExpression);
527
528 Task _ = Task.Run(async () =>
529 {
530 try
531 {
532 object Obj = await Exp.EvaluateAsync(NoteParameters);
533
534 if (Obj is string s)
535 await this.client.AddTextNoteAsync(this.TokenId, s, Command.Personal);
536 else if (Obj is XmlDocument Xml)
537 await this.client.AddXmlNoteAsync(this.TokenId, Xml.DocumentElement.OuterXml, Command.Personal);
538 else if (Obj is XmlElement E)
539 await this.client.AddXmlNoteAsync(this.TokenId, E.OuterXml, Command.Personal);
540 else if (Obj is null)
541 throw new Exception("Note command returned null.");
542 else
543 throw new Exception("Command generated note of uncompatible type: " + Obj.GetType().FullName);
544
545 this.NoteAdded?.Invoke(this, EventArgs.Empty);
546
547 Msg = Command.Success?.Find(this.language);
548 if (!string.IsNullOrEmpty(Msg))
549 await MainWindow.MessageBox(Msg, "Success", MessageBoxButton.OK, MessageBoxImage.Information);
550 }
551 catch (Exception ex)
552 {
553 Msg = Command.Failure?.Find(this.language);
554 MainWindow.ErrorBox(string.IsNullOrEmpty(Msg) ? ex.Message : Msg);
555 }
556 });
557 }
558 catch (Exception ex)
559 {
560 Msg = Command.Failure?.Find(this.language);
561 MainWindow.ErrorBox(string.IsNullOrEmpty(Msg) ? ex.Message : Msg);
562 }
563 }
564 }
565 catch (Exception ex)
566 {
567 Log.Exception(ex);
568 }
569 }
570
574 public event EventHandler NoteAdded;
575
580 public void StateUpdated(string NewState)
581 {
582 this.currentState = NewState;
583 }
584
589 public void VariablesUpdated(Variables NewVariables)
590 {
591 this.currentVariables = NewVariables;
592 }
593
597 public string CurrentState => this.currentState;
598
602 public Variables CurrentVariables => this.currentVariables;
603 }
604}
Information about a note command related to the state-machine associated with the token.
Definition: NoteCommand.cs:17
bool HasNoteContextScript
If a valid expression for note context is available.
Definition: NoteCommand.cs:271
Expression ParsedNoteContextScript
Parsed note context script. If null, script is either not defined, or it contains errors.
Definition: NoteCommand.cs:249
LocalizedString[] ToolTip
Tool-tip of command.
Definition: NoteCommand.cs:174
bool ExternalNote
If note can be added by authorized external sources.
Definition: NoteCommand.cs:159
bool OwnerNote
If note can be added by owner.
Definition: NoteCommand.cs:154
LocalizedString[] Title
Title of command.
Definition: NoteCommand.cs:169
Abstract base class for token tag references.
Definition: TokenTag.cs:12
abstract object Value
Object value.
Definition: TokenTag.cs:37
CaseInsensitiveString Name
Tag Name
Definition: TokenTag.cs:32
Neuro-Feature Token
Definition: Token.cs:43
async Task< NoteCommand[]> GetNoteCommands()
Gets
Definition: Token.cs:1113
Duration? ArchiveRequired
Duration after which token expires, the token is required to be archived.
Definition: Token.cs:336
string Category
A category for the token.
Definition: Token.cs:435
string Currency
Currency used to represent latest value.
Definition: Token.cs:201
string TrustProvider
Trust Provider, asserting claims in the token.
Definition: Token.cs:183
string TrustProviderJid
JID of Trust Provider, asserting claims in the token.
Definition: Token.cs:192
int GlyphWidth
Width of glyph, in pixels.
Definition: Token.cs:476
DateTime Expires
Expiry date of token.
Definition: Token.cs:327
decimal Value
Latest value of token
Definition: Token.cs:300
DateTime Updated
When token was updated.
Definition: Token.cs:318
int GlyphHeight
Height of glyph, in pixels.
Definition: Token.cs:485
string CreationContract
ID of contract that details the claims of the current owner
Definition: Token.cs:237
int BatchSize
Size of the batch of contracts created.
Definition: Token.cs:503
string OwnershipContract
ID of contract that details the claims of the current owner
Definition: Token.cs:246
string FriendlyName
A friendly name for the token.
Definition: Token.cs:426
bool CertifierCanDestroy
If a certifier is allowed to destroy the token.
Definition: Token.cs:417
Duration? ArchiveOptional
Duration after which token expires, and the required archiving time, the token can optionally be arch...
Definition: Token.cs:345
bool CreatorCanDestroy
If the creator is allowed to destroy the token.
Definition: Token.cs:390
DateTime Created
When token was created.
Definition: Token.cs:309
DateTime SignatureTimestamp
When the Trust Provider signed the contents of the token.
Definition: Token.cs:354
string OwnerJid
JID of Current owner of token
Definition: Token.cs:174
ContractVisibility Visibility
Token visibility
Definition: Token.cs:138
byte[] DefinitionSchemaDigest
Hash Digest of schema used to validate the definition of the token.
Definition: Token.cs:372
HashFunction DefinitionSchemaHashFunction
Hash function used to compute digest of validation schema.
Definition: Token.cs:381
string ShortId
Short ID, if available
Definition: Token.cs:120
string DefinitionNamespace
Namespace of M2M definition of token.
Definition: Token.cs:228
string Creator
Creator of token
Definition: Token.cs:147
string GlyphContentType
Content-Type of glyph
Definition: Token.cs:467
bool OwnerCanDestroyIndividual
If the current owner is allowed to destroy the token individually.
Definition: Token.cs:408
string Description
Description Markdown for the token.
Definition: Token.cs:444
int Ordinal
Ordinal of token created by the creation smart contract.
Definition: Token.cs:494
string Definition
M2M definition of token, in XML, from the original creation contract.
Definition: Token.cs:219
byte[] Signature
Trust Provider Signature of contents in token.
Definition: Token.cs:363
bool OwnerCanDestroyBatch
If the current owner is allowed to destroy the entire batch of tokens, if owner of all.
Definition: Token.cs:399
string TokenId
Token ID
Definition: Token.cs:111
byte[] Glyph
Token glyph
Definition: Token.cs:458
TokenIdMethod TokenIdMethod
The method used to create the Token ID.
Definition: Token.cs:102
string Owner
Current owner of token
Definition: Token.cs:165
string Reference
Link to reference information.
Definition: Token.cs:210
string CreatorJid
JID of Creator of token
Definition: Token.cs:156
Contains a markdown document. This markdown document class supports original markdown,...
static Task< MarkdownDocument > CreateAsync(string MarkdownText, params Type[] TransparentExceptionTypes)
Contains a markdown document. This markdown document class supports original markdown,...
Static class managing the application event log. Applications and services log events on this static ...
Definition: Log.cs:13
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.
Definition: Log.cs:1647
Abstract base class for contractual parameters
Definition: Parameter.cs:17
Class managing a script expression.
Definition: Expression.cs:39
async Task< object > EvaluateAsync(Variables Variables)
Evaluates the expression, using the variables provided in the Variables collection....
Definition: Expression.cs:4275
Base class for all nodes in a parsed script tree.
Definition: ScriptNode.cs:69
Collection of variables.
Definition: Variables.cs:25
void CopyTo(Variables Variables)
Copies available variables to another variable collection.
Definition: Variables.cs:400
ContractVisibility
Visibility types for contracts.
Definition: Enumerations.cs:58
Definition: App.xaml.cs:4