ソースを参照

Wizards: encapsulate fee, payload and signer models

Herman Schoenfeld 7 年 前
コミット
a7ab36eba3

+ 3 - 3
src/core/UDataSources.pas

@@ -364,7 +364,7 @@ begin
       if list.Count > 0 then
         for i := list.Count - 1 downto 0 do begin
           Op := node.Operations.OperationsHashTree.GetOperation( PtrInt( list[i] ) );
-          If TPCOperation.OperationToOperationResume( 0, Op, acc, OPR ) then begin
+          If TPCOperation.OperationToOperationResume( 0, Op, false, acc, OPR ) then begin
             OPR.NOpInsideBlock := i;
             OPR.Block := Node.Operations.OperationBlock.block; ;
             OPR.Balance := Node.Operations.SafeBoxTransaction.Account( acc {Op.SignerAccount} ).balance;
@@ -395,7 +395,7 @@ begin
   if Not Assigned(Node) then exit;
   for i := Node.Operations.Count - 1 downto 0 do begin
     Op := Node.Operations.OperationsHashTree.GetOperation(i);
-    If TPCOperation.OperationToOperationResume(0,Op,Op.SignerAccount,OPR) then begin
+    If TPCOperation.OperationToOperationResume(0,Op, false, Op.SignerAccount,OPR) then begin
       OPR.NOpInsideBlock := i;
       OPR.Block := Node.Bank.BlocksCount;
       OPR.Balance := Node.Operations.SafeBoxTransaction.Account(Op.SignerAccount).balance;
@@ -424,7 +424,7 @@ begin
       AContainer.Add( blockOps.GetMinerRewardPseudoOperation );
       if blockOps.Count = 0 then exit;
       for i := blockOps.Count - 1 downto 0 do begin    // reverse order
-        if TPCOperation.OperationToOperationResume(block, blockOps.Operation[i], blockOps.Operation[i].SignerAccount, opr) then begin
+        if TPCOperation.OperationToOperationResume(block, blockOps.Operation[i], false, blockOps.Operation[i].SignerAccount, opr) then begin
           opr.NOpInsideBlock := i;
           opr.Block := block;
           opr.time := blockOps.OperationBlock.timestamp;

+ 1 - 1
src/gui/UCTRLWallet.lfm

@@ -10,7 +10,7 @@ object CTRLWallet: TCTRLWallet
   ClientWidth = 1151
   OnCreate = FormCreate
   OnResize = FormResize
-  LCLVersion = '1.8.1.0'
+  LCLVersion = '1.8.2.0'
   Visible = False
   object PairSplitter1: TPairSplitter
     Left = 0

+ 5 - 21
src/gui/UCTRLWallet.pas

@@ -609,36 +609,20 @@ end;
 
 procedure TCTRLWallet.OnPrepareAccountPopupMenu(Sender: TObject;
   constref ASelection: TVisualGridSelection; out APopupMenu: TPopupMenu);
-var
-  accNo: cardinal;
-  account: TAccount;
 begin
   miSep1.Visible := ASelection.RowCount = 1;
   miAccountInfo.Visible := ASelection.RowCount = 1;
-  miSendPASC.Caption :=
-    IIF(ASelection.RowCount = 1, 'Send PASC', 'Send All PASC');
   miTransferAccounts.Caption :=
-    IIF(ASelection.RowCount = 1, 'Transfer Account', 'Transfer All Account');
+    IIF(ASelection.RowCount = 1, 'Transfer Account', 'Transfer Accounts');
   miChangeAccountsPrivateKey.Caption :=
-    IIF(ASelection.RowCount = 1, 'Change Account Private Key', 'Change All Account Private Key');
+    IIF(ASelection.RowCount = 1, 'Change Account Private Key',
+    'Change Accounts Private Key');
   miEnlistAccountsForSale.Caption :=
     IIF(ASelection.RowCount = 1, 'Enlist Account For Sale',
-    'Enlist All Account For Sale');
+    'Enlist Accounts For Sale');
   miDelistAccountsFromSale.Caption :=
     IIF(ASelection.RowCount = 1, 'Delist Account From Sale',
-    'Delist All Account From Sale');
-  if ASelection.RowCount = 1 then
-  begin
-    if not TAccountComp.AccountTxtNumberToAccountNumber(
-      FAccountsGrid.Rows[ASelection.Row].Account, accNo) then
-    begin
-      raise Exception.Create('Error Parsing Account Number From Grid');
-    end;
-    account := TNode.Node.Operations.SafeBoxTransaction.Account(accNo);
-    miEnlistAccountsForSale.Visible :=
-      IIF(TAccountComp.IsAccountForSale(account.accountInfo), False, True);
-    miDelistAccountsFromSale.Visible := not miEnlistAccountsForSale.Visible;
-  end;
+    'Delist Accounts From Sale');
   APopupMenu := mnuAccountsPopup;
 end;
 

+ 15 - 16
src/gui/wizards/UWIZChangeAccountPrivateKey.pas

@@ -47,8 +47,7 @@ uses
 
 { TWIZChangeAccountPrivateKeyWizard }
 
-function TWIZChangeAccountPrivateKeyWizard.UpdatePayload(const SenderAccount: TAccount;
-  var errors: string): boolean;
+function TWIZChangeAccountPrivateKeyWizard.UpdatePayload(const SenderAccount: TAccount; var errors: string): boolean;
 var
   valid: boolean;
   payload_encrypted, payload_u: string;
@@ -57,9 +56,9 @@ var
 begin
   valid := False;
   payload_encrypted := '';
-  Model.ChangeAccountPrivateKeyModel.EncodedPayload := '';
+  Model.PayloadModel.EncodedPayload := '';
   errors := 'Unknown error';
-  payload_u := Model.ChangeAccountPrivateKeyModel.Payload;
+  payload_u := Model.PayloadModel.Payload;
 
   try
     if (payload_u = '') then
@@ -67,9 +66,9 @@ begin
       valid := True;
       Exit;
     end;
-    case Model.ChangeAccountPrivateKeyModel.PayloadEncryptionMode of
+    case Model.PayloadModel.PayloadEncryptionMode of
 
-      akaEncryptWithSender:
+      akaEncryptWithOldEC:
       begin
         // Use sender
         errors := 'Error encrypting';
@@ -78,7 +77,7 @@ begin
         valid := payload_encrypted <> '';
       end;
 
-      akaEncryptWithReceiver:
+      akaEncryptWithEC:
       begin
         errors := 'Error encrypting';
 
@@ -100,7 +99,7 @@ begin
       akaEncryptWithPassword:
       begin
         payload_encrypted := TAESComp.EVP_Encrypt_AES256(
-          payload_u, Model.ChangeAccountPrivateKeyModel.EncryptionPassword);
+          payload_u, Model.PayloadModel.EncryptionPassword);
         valid := payload_encrypted <> '';
       end;
 
@@ -127,7 +126,7 @@ begin
       end;
 
     end;
-    Model.ChangeAccountPrivateKeyModel.EncodedPayload := payload_encrypted;
+    Model.PayloadModel.EncodedPayload := payload_encrypted;
     Result := valid;
   end;
 
@@ -206,7 +205,7 @@ begin
     if TNode.Node.Bank.SafeBox.CurrentProtocol >= 1 then
     begin
       // Signer:
-      SignerAccount := Model.ChangeAccountPrivateKeyModel.SignerAccount;
+      SignerAccount := Model.SignerModel.SignerAccount;
       if (TAccountComp.IsAccountLocked(SignerAccount.accountInfo,
         TNode.Node.Bank.BlocksCount)) then
       begin
@@ -289,8 +288,8 @@ begin
       wk := TWallet.Keys.Key[i];
       dooperation := True;
       // Default fee
-      if account.balance > uint64(Model.ChangeAccountPrivateKeyModel.DefaultFee) then
-        _fee := Model.ChangeAccountPrivateKeyModel.DefaultFee
+      if account.balance > uint64(Model.FeeModel.DefaultFee) then
+        _fee := Model.FeeModel.DefaultFee
       else
         _fee := account.balance;
 
@@ -314,13 +313,13 @@ begin
         if uint64(_totalSignerFee) >= signerAccount.balance then
           _fee := 0
         else if signerAccount.balance - uint64(_totalSignerFee) >
-          uint64(Model.ChangeAccountPrivateKeyModel.DefaultFee) then
-          _fee := Model.ChangeAccountPrivateKeyModel.DefaultFee
+          uint64(Model.FeeModel.DefaultFee) then
+          _fee := Model.FeeModel.DefaultFee
         else
           _fee := signerAccount.balance - uint64(_totalSignerFee);
         op := TOpChangeKeySigned.Create(signerAccount.account,
           signerAccount.n_operation + _signer_n_ops + 1, account.account,
-          wk.PrivateKey, _newOwnerPublicKey, _fee, Model.ChangeAccountPrivateKeyModel.EncodedPayload);
+          wk.PrivateKey, _newOwnerPublicKey, _fee, Model.PayloadModel.EncodedPayload);
         Inc(_signer_n_ops);
         Inc(_totalSignerFee, _fee);
       end
@@ -328,7 +327,7 @@ begin
       begin
         op := TOpChangeKey.Create(account.account, account.n_operation +
           1, account.account, wk.PrivateKey, _newOwnerPublicKey, _fee,
-          Model.ChangeAccountPrivateKeyModel.EncodedPayload);
+          Model.PayloadModel.EncodedPayload);
       end;
       Inc(_totalfee, _fee);
       operationstxt :=

+ 11 - 13
src/gui/wizards/UWIZChangeAccountPrivateKey_Confirmation.pas

@@ -44,11 +44,11 @@ type
 
   TAccountSenderDataSource = class(TAccountsDataSourceBase)
   private
-    FModel: TWIZOperationsModel.TChangeAccountPrivateKeyModel;
+    FModel: TWIZOperationsModel;
   protected
     function GetColumns: TDataColumns; override;
   public
-    property Model: TWIZOperationsModel.TChangeAccountPrivateKeyModel read FModel write FModel;
+    property Model: TWIZOperationsModel read FModel write FModel;
     procedure FetchAll(const AContainer: TList<TAccount>); override;
     function GetItemField(constref AItem: TAccount;
       const ABindingName: ansistring): variant; override;
@@ -89,10 +89,10 @@ begin
   end;
 
   Data := TAccountSenderDataSource.Create(FSendersGrid);
-  Data.Model := Model.ChangeAccountPrivateKeyModel;
+  Data.Model := Model;
   FSendersGrid.DataSource := Data;
   paGrid.AddControlDockCenter(FSendersGrid);
-  lblSgnAcc.Caption := TAccountComp.AccountNumberToAccountTxtNumber(Model.ChangeAccountPrivateKeyModel.SignerAccount.account);
+  lblSgnAcc.Caption := TAccountComp.AccountNumberToAccountTxtNumber(Model.SignerModel.SignerAccount.account);
 end;
 
 { TAccountSenderDataSource }
@@ -106,8 +106,7 @@ begin
     );
 end;
 
-function TAccountSenderDataSource.GetItemField(constref AItem: TAccount;
-  const ABindingName: ansistring): variant;
+function TAccountSenderDataSource.GetItemField(constref AItem: TAccount; const ABindingName: ansistring): variant;
 var
   index: integer;
 begin
@@ -115,16 +114,15 @@ begin
     Result := TAccountComp.AccountNumberToAccountTxtNumber(AItem.account)
   else if ABindingName = 'NewPrivateKey' then
   begin
-    Result := IIF(Model.NewWalletKey.Name = '',
-      TCrypto.ToHexaString(TAccountComp.AccountKey2RawString(
-      Model.NewWalletKey.AccountKey)), Model.NewWalletKey.Name);
-    if not Assigned(Model.NewWalletKey.PrivateKey) then
+    Result := IIF(Model.ChangeAccountPrivateKeyModel.NewWalletKey.Name = '',
+      TCrypto.ToHexaString(TAccountComp.AccountKey2RawString(Model.ChangeAccountPrivateKeyModel.NewWalletKey.AccountKey)), Model.ChangeAccountPrivateKeyModel.NewWalletKey.Name);
+    if not Assigned(Model.ChangeAccountPrivateKeyModel.NewWalletKey.PrivateKey) then
     begin
       Result := Result + '(*)';
     end;
   end
   else if ABindingName = 'Fee' then
-    Result := TAccountComp.FormatMoney(Model.DefaultFee)
+    Result := TAccountComp.FormatMoney(Model.FeeModel.DefaultFee)
   else
     raise Exception.Create(Format('Field not found [%s]', [ABindingName]));
 end;
@@ -134,9 +132,9 @@ procedure TAccountSenderDataSource.FetchAll(const AContainer: TList<TAccount>);
 var
   i: integer;
 begin
-  for i := Low(Model.SelectedAccounts) to High(Model.SelectedAccounts) do
+  for i := Low(Model.ChangeAccountPrivateKeyModel.SelectedAccounts) to High(Model.ChangeAccountPrivateKeyModel.SelectedAccounts) do
   begin
-    AContainer.Add(Model.SelectedAccounts[i]);
+    AContainer.Add(Model.ChangeAccountPrivateKeyModel.SelectedAccounts[i]);
   end;
 end;
 

+ 2 - 2
src/gui/wizards/UWIZChangeAccountPrivateKey_Transaction.pas

@@ -163,7 +163,7 @@ procedure TWIZChangeAccountPrivateKey_Transaction.OnNext;
 begin
   Model.ChangeAccountPrivateKeyModel.SelectedIndex := cbSignerAccount.ItemIndex;
   Model.ChangeAccountPrivateKeyModel.PrivateKeySelectedIndex := cbNewPrivateKey.ItemIndex;
-  Model.ChangeAccountPrivateKeyModel.SignerAccount := Model.ChangeAccountPrivateKeyModel.SelectedAccounts[PtrInt(cbSignerAccount.Items.Objects[cbSignerAccount.ItemIndex])];
+  Model.SignerModel.SignerAccount := Model.ChangeAccountPrivateKeyModel.SelectedAccounts[PtrInt(cbSignerAccount.Items.Objects[cbSignerAccount.ItemIndex])];
   Model.ChangeAccountPrivateKeyModel.NewWalletKey := TWallet.Keys.Key[PtrInt(cbNewPrivateKey.Items.Objects[cbNewPrivateKey.ItemIndex])];
 
   UpdatePath(ptReplaceAllNext, [TWIZChangeAccountPrivateKey_TransactionPayload, TWIZChangeAccountPrivateKey_Confirmation]);
@@ -187,7 +187,7 @@ begin
     Exit;
   end;
 
-  if not TAccountComp.TxtToMoney(Trim(edtOpFee.Text), Model.ChangeAccountPrivateKeyModel.DefaultFee) then
+  if not TAccountComp.TxtToMoney(Trim(edtOpFee.Text), Model.FeeModel.DefaultFee) then
   begin
     message := 'Invalid fee value "' + edtOpFee.Text + '"';
     Result := False;

+ 1 - 0
src/gui/wizards/UWIZChangeAccountPrivateKey_TransactionPayload.lfm

@@ -7,6 +7,7 @@ object WIZChangeAccountPrivateKey_TransactionPayload: TWIZChangeAccountPrivateKe
   Caption = 'Form1'
   ClientHeight = 253
   ClientWidth = 429
+  LCLVersion = '1.8.2.0'
   Visible = False
   object grpPayload: TGroupBox
     Left = 8

+ 5 - 5
src/gui/wizards/UWIZChangeAccountPrivateKey_TransactionPayload.pas

@@ -48,25 +48,25 @@ uses
 
 procedure TWIZChangeAccountPrivateKey_TransactionPayload.OnNext;
 begin
-  Model.ChangeAccountPrivateKeyModel.Payload := mmoPayload.Lines.Text;
+  Model.PayloadModel.Payload := mmoPayload.Lines.Text;
   if rbEncryptedWithOldEC.Checked then
   begin
-    Model.ChangeAccountPrivateKeyModel.PayloadEncryptionMode := akaEncryptWithSender;
+    Model.PayloadModel.PayloadEncryptionMode := akaEncryptWithOldEC;
   end
   else
   if rbEncryptedWithEC.Checked then
   begin
-    Model.ChangeAccountPrivateKeyModel.PayloadEncryptionMode := akaEncryptWithReceiver;
+    Model.PayloadModel.PayloadEncryptionMode := akaEncryptWithEC;
   end
   else
   if rbEncryptedWithPassword.Checked then
   begin
-    Model.ChangeAccountPrivateKeyModel.PayloadEncryptionMode := akaEncryptWithPassword;
+    Model.PayloadModel.PayloadEncryptionMode := akaEncryptWithPassword;
   end
   else
   if rbNotEncrypted.Checked then
   begin
-    Model.ChangeAccountPrivateKeyModel.PayloadEncryptionMode := akaNotEncrypt;
+    Model.PayloadModel.PayloadEncryptionMode := akaNotEncrypt;
   end;
 end;
 

+ 83 - 74
src/gui/wizards/UWIZModels.pas

@@ -7,8 +7,7 @@ unit UWIZModels;
 
 interface
 
-uses Classes, SysUtils, UWizard, UAccounts, UBlockChain, UWallet,
-  UBaseTypes, Generics.Defaults;
+uses Classes, SysUtils, UWizard, UAccounts, UBlockChain, UWallet, UBaseTypes, Generics.Defaults;
 
 type
 
@@ -19,101 +18,111 @@ type
   { TFRMAddKeyModel }
 
   TWIZAddKeyModel = class(TComponent)
-  public
-    Name: string;
-    KeyText: string;
-    Password: string;
-    EncryptionTypeNID: word;
-    Action: TWIZAddKeyAction;
+    public
+      Name : String;
+      KeyText : String;
+      Password : String;
+      EncryptionTypeNID : word;
+      Action : TWIZAddKeyAction;
   end;
 
   { TWIZOperationsModel }
 
-  TWIZOperationsModel = class(TComponent)
-  public
-    type
+  TWIZOperationsModel = class (TComponent)
+    public type
 
-    { TModelType }
+       { TModelType }
 
-    TModelType = (omtSendPasc, omtTransferAccount, omtChangeAccountPrivateKey,
-      omtAddKey);
+       TModelType = (omtSendPasc, omtTransferAccount, omtChangeAccountPrivateKey, omtAddKey);
 
-    { TPayloadEncryptionMode }
+       { TPayloadEncryptionMode }
 
-    TPayloadEncryptionMode = (akaEncryptWithSender, akaEncryptWithReceiver,
-      akaEncryptWithPassword, akaNotEncrypt);
+       TPayloadEncryptionMode = (akaEncryptWithOldEC, akaEncryptWithEC, akaEncryptWithPassword, akaNotEncrypt);
 
-    { TOperationSigningMode }
+       { TSendPASCModel }
 
-    TOperationSigningMode = (akaPrimary, akaSecondary);
+       TSendPASCModel = class(TComponent)
+       public
+         SelectedIndex: integer;
+         AmountToSend : string;
+         DestinationAccount: TAccount;
+         SelectedAccounts: TArray<TAccount>;
+       end;
 
-    { TSendPASCModel }
+       { TTransferAccountModel }
 
-    TSendPASCModel = class(TComponent)
-    public
-      SelectedIndex: integer;
-      SingleOperationFee, SingleAmountToSend: int64;
-      HasPayload: boolean;
-      PayloadContent, EncryptionPassword: string;
-      EncodedPayload: TRawBytes;
-      SignerAccount, DestinationAccount: TAccount;
-      SelectedAccounts: TArray<TAccount>;
-      PayloadEncryptionMode: TPayloadEncryptionMode;
-      OperationSigningMode: TOperationSigningMode;
-    end;
-
-    { TTransferAccountModel }
-
-    TTransferAccountModel = class(TComponent)
-    public
-      DefaultFee: int64;
-      NewPublicKey, Payload, EncryptionPassword: string;
-      SelectedIndex: integer;
-      AccountKey: TAccountKey;
-      EncodedPayload: TRawBytes;
-      SignerAccount: TAccount;
-      SelectedAccounts: TArray<TAccount>;
-      PayloadEncryptionMode: TPayloadEncryptionMode;
-    end;
-
-    { TChangeAccountPrivateKeyModel }
-
-    TChangeAccountPrivateKeyModel = class(TComponent)
+       TTransferAccountModel = class(TComponent)
+       public
+         NewPublicKey: string;
+         SelectedIndex: integer;
+         AccountKey: TAccountKey;
+         SelectedAccounts: TArray<TAccount>;
+       end;
+
+       { TChangeAccountPrivateKeyModel }
+
+       TChangeAccountPrivateKeyModel = class(TComponent)
+       public
+         NewPublicKey: string;
+         SelectedIndex, PrivateKeySelectedIndex: integer;
+         NewWalletKey: TWalletKey;
+         SelectedAccounts: TArray<TAccount>;
+       end;
+
+       { TFeeModel }
+
+       TFeeModel = class(TComponent)
+       public
+         DefaultFee: int64;
+       end;
+
+       { TSignerModel }
+
+       TSignerModel = class(TComponent)
+       public
+         SignerAccount: TAccount;
+       end;
+
+       { TPayloadModel }
+
+       TPayloadModel = class(TComponent)
+       public
+         Payload, EncryptionPassword : string;
+         PayloadEncryptionMode: TPayloadEncryptionMode;
+         EncodedPayload: TRawBytes;
+       end;
+
+    private
+      FModelType : TModelType;
+      FSendModel : TSendPASCModel;
+      FTransferAccountModel : TTransferAccountModel;
+      FChangeAccountPrivateKeyModel : TChangeAccountPrivateKeyModel;
+      FFeeModel : TFeeModel;
+      FSignerModel : TSignerModel;
+      FPayloadModel : TPayloadModel;
     public
-      DefaultFee: int64;
-      NewPublicKey, Payload, EncryptionPassword: string;
-      SelectedIndex, PrivateKeySelectedIndex: integer;
-      NewWalletKey: TWalletKey;
-      EncodedPayload: TRawBytes;
-      SignerAccount: TAccount;
-      SelectedAccounts: TArray<TAccount>;
-      PayloadEncryptionMode: TPayloadEncryptionMode;
-    end;
-
-  private
-    FModelType: TModelType;
-    FSendModel: TSendPASCModel;
-    FTransferAccountModel: TTransferAccountModel;
-    FChangeAccountPrivateKeyModel: TChangeAccountPrivateKeyModel;
-  public
-    constructor Create(AOwner: TComponent; AType: TModelType); overload;
-    property ModelType: TModelType read FModelType;
-    property SendPASCModel: TSendPASCModel read FSendModel;
-    property TransferAccountModel: TTransferAccountModel read FTransferAccountModel;
-    property ChangeAccountPrivateKeyModel: TChangeAccountPrivateKeyModel
-      read FChangeAccountPrivateKeyModel;
+      constructor Create(AOwner : TComponent; AType : TModelType);  overload;
+      property ModelType : TModelType read FModelType;
+      property SendPASCModel : TSendPASCModel read FSendModel;
+      property TransferAccountModel : TTransferAccountModel read FTransferAccountModel;
+      property ChangeAccountPrivateKeyModel : TChangeAccountPrivateKeyModel read FChangeAccountPrivateKeyModel;
+      property FeeModel : TFeeModel read FFeeModel;
+      property SignerModel : TSignerModel read FSignerModel;
+      property PayloadModel : TPayloadModel read FPayloadModel;
   end;
 
 implementation
 
-constructor TWIZOperationsModel.Create(AOwner: TComponent;
-  AType: TWIZOperationsModel.TModelType);
+constructor TWIZOperationsModel.Create(AOwner : TComponent; AType : TWIZOperationsModel.TModelType);
 begin
   inherited Create(AOwner);
   FModelType := AType;
   FSendModel := TSendPASCModel.Create(Self);
   FTransferAccountModel := TTransferAccountModel.Create(Self);
   FChangeAccountPrivateKeyModel := TChangeAccountPrivateKeyModel.Create(Self);
+  FFeeModel := TFeeModel.Create(Self);
+  FSignerModel := TSignerModel.Create(Self);
 end;
 
 end.
+

+ 29 - 35
src/gui/wizards/UWIZSendPASC.pas

@@ -22,11 +22,9 @@ type
 
   TWIZSendPASCWizard = class(TWizard<TWIZOperationsModel>)
   private
-    function UpdatePayload(const SenderAccount: TAccount;
-      var errors: string): boolean;
+    function UpdatePayload(const SenderAccount: TAccount; var errors: string): boolean;
     function UpdateOperationOptions(var errors: string): boolean;
-    function UpdateOpTransaction(const SenderAccount: TAccount;
-      var DestAccount: TAccount; var amount: int64; var errors: string): boolean;
+    function UpdateOpTransaction(const SenderAccount: TAccount; var DestAccount: TAccount; var amount: int64; var errors: string): boolean;
     procedure SendPASC();
   public
     constructor Create(AOwner: TComponent); override;
@@ -46,7 +44,7 @@ uses
   UWallet,
   UECIES,
   UAES,
-  UWIZSendPASC_ConfirmSender,
+  UWIZSendPASC_Start,
   UWIZSendPASC_Confirmation;
 
 { TWIZSendPASCWizard }
@@ -81,9 +79,7 @@ begin
       iWallet := TWallet.Keys.IndexOfAccountKey(sender_account.accountInfo.accountKey);
       if (iWallet < 0) then
       begin
-        errors := 'Private key of account ' +
-          TAccountComp.AccountNumberToAccountTxtNumber(sender_account.account) +
-          ' not found in wallet';
+        errors := 'Private key of account ' + TAccountComp.AccountNumberToAccountTxtNumber(sender_account.account) + ' not found in wallet';
         Exit;
       end;
       wk := TWallet.Keys.Key[iWallet];
@@ -97,8 +93,7 @@ begin
         else
         begin
           errors := 'Only public key of account ' +
-            TAccountComp.AccountNumberToAccountTxtNumber(sender_account.account) +
-            ' found in wallet. You cannot operate with this account';
+            TAccountComp.AccountNumberToAccountTxtNumber(sender_account.account) + ' found in wallet. You cannot operate with this account';
         end;
         Exit;
       end;
@@ -109,8 +104,7 @@ begin
   UpdatePayload(sender_account, e);
 end;
 
-function TWIZSendPASCWizard.UpdateOpTransaction(const SenderAccount: TAccount;
-  var DestAccount: TAccount; var amount: int64; var errors: string): boolean;
+function TWIZSendPASCWizard.UpdateOpTransaction(const SenderAccount: TAccount; var DestAccount: TAccount; var amount: int64; var errors: string): boolean;
 var
   c: cardinal;
 begin
@@ -121,7 +115,11 @@ begin
 
   if Length(Model.SendPASCModel.SelectedAccounts) = 1 then
   begin
-    amount := Model.SendPASCModel.SingleAmountToSend;
+    if not TAccountComp.TxtToMoney(Model.SendPASCModel.AmountToSend, amount) then
+    begin
+      errors := 'Invalid amount (' + Model.SendPASCModel.AmountToSend + ')';
+      Exit;
+    end;
   end
   else
   begin
@@ -136,7 +134,7 @@ begin
 
   if (Length(Model.SendPASCModel.SelectedAccounts) = 1) then
   begin
-    if (SenderAccount.balance < (amount + Model.SendPASCModel.SingleOperationFee)) then
+    if (SenderAccount.balance < (amount + Model.FeeModel.DefaultFee)) then
     begin
       errors := 'Insufficient funds';
       Exit;
@@ -188,8 +186,8 @@ begin
       wk := TWallet.Keys.Key[i];
       dooperation := True;
       // Default fee
-      if account.balance > uint64(Model.SendPASCModel.SingleOperationFee) then
-        _fee := Model.SendPASCModel.SingleOperationFee
+      if account.balance > uint64(Model.FeeModel.DefaultFee) then
+        _fee := Model.FeeModel.DefaultFee
       else
         _fee := account.balance;
 
@@ -199,10 +197,10 @@ begin
       begin
         if account.balance > 0 then
         begin
-          if account.balance > Model.SendPASCModel.SingleOperationFee then
+          if account.balance > Model.FeeModel.DefaultFee then
           begin
-            _amount := account.balance - Model.SendPASCModel.SingleOperationFee;
-            _fee := Model.SendPASCModel.SingleOperationFee;
+            _amount := account.balance - Model.FeeModel.DefaultFee;
+            _fee := Model.FeeModel.DefaultFee;
           end
           else
           begin
@@ -220,12 +218,11 @@ begin
       begin
         op := TOpTransaction.CreateTransaction(
           account.account, account.n_operation + 1, destAccount.account,
-          wk.PrivateKey, _amount, _fee, Model.SendPASCModel.EncodedPayload);
+          wk.PrivateKey, _amount, _fee, Model.PayloadModel.EncodedPayload);
         Inc(_totalamount, _amount);
         Inc(_totalfee, _fee);
       end;
-      operationstxt := 'Transaction to ' + TAccountComp.AccountNumberToAccountTxtNumber(
-        destAccount.account);
+      operationstxt := 'Transaction to ' + TAccountComp.AccountNumberToAccountTxtNumber(destAccount.account);
 
       if Assigned(op) and (dooperation) then
       begin
@@ -242,8 +239,7 @@ begin
 
     if (Length(Model.SendPASCModel.SelectedAccounts) > 1) then
     begin
-      auxs := 'Total amount that dest will receive: ' + TAccountComp.FormatMoney(
-        _totalamount) + #10;
+      auxs := 'Total amount that dest will receive: ' + TAccountComp.FormatMoney(_totalamount) + #10;
       if Application.MessageBox(
         PChar('Execute ' + IntToStr(Length(Model.SendPASCModel.SelectedAccounts)) +
         ' operations?' + #10 + 'Operation: ' + operationstxt + #10 +
@@ -316,8 +312,7 @@ begin
   end;
 end;
 
-function TWIZSendPASCWizard.UpdatePayload(const SenderAccount: TAccount;
-  var errors: string): boolean;
+function TWIZSendPASCWizard.UpdatePayload(const SenderAccount: TAccount; var errors: string): boolean;
 var
   valid: boolean;
   payload_encrypted, payload_u: string;
@@ -325,9 +320,9 @@ var
 begin
   valid := False;
   payload_encrypted := '';
-  Model.SendPASCModel.EncodedPayload := '';
+  Model.PayloadModel.EncodedPayload := '';
   errors := 'Unknown error';
-  payload_u := Model.SendPASCModel.PayloadContent;
+  payload_u := Model.PayloadModel.Payload;
 
   try
     if (payload_u = '') then
@@ -335,9 +330,9 @@ begin
       valid := True;
       Exit;
     end;
-    case Model.SendPASCModel.PayloadEncryptionMode of
+    case Model.PayloadModel.PayloadEncryptionMode of
 
-      akaEncryptWithSender:
+      akaEncryptWithOldEC:
       begin
         // Use sender
         errors := 'Error encrypting';
@@ -346,7 +341,7 @@ begin
         valid := payload_encrypted <> '';
       end;
 
-      akaEncryptWithReceiver:
+      akaEncryptWithEC:
       begin
         // With dest public key
         errors := 'Error encrypting';
@@ -357,8 +352,7 @@ begin
 
       akaEncryptWithPassword:
       begin
-        payload_encrypted := TAESComp.EVP_Encrypt_AES256(
-          payload_u, Model.SendPASCModel.EncryptionPassword);
+        payload_encrypted := TAESComp.EVP_Encrypt_AES256(payload_u, Model.PayloadModel.EncryptionPassword);
         valid := payload_encrypted <> '';
       end;
 
@@ -385,7 +379,7 @@ begin
       end;
 
     end;
-    Model.SendPASCModel.EncodedPayload := payload_encrypted;
+    Model.PayloadModel.EncodedPayload := payload_encrypted;
     Result := valid;
   end;
 
@@ -393,7 +387,7 @@ end;
 
 constructor TWIZSendPASCWizard.Create(AOwner: TComponent);
 begin
-  inherited Create(AOwner, [TWIZSendPASC_ConfirmSender, TWIZSendPASC_Confirmation]);
+  inherited Create(AOwner, [TWIZSendPASC_Start, TWIZSendPASC_Confirmation]);
   TitleText := 'Send PASC';
   FinishText := 'Send PASC';
 end;

+ 1 - 0
src/gui/wizards/UWIZSendPASC_Confirmation.lfm

@@ -6,6 +6,7 @@ object WIZSendPASC_Confirmation: TWIZSendPASC_Confirmation
   Caption = 'WIZSendPASC_Confirmation'
   ClientHeight = 253
   ClientWidth = 429
+  LCLVersion = '1.8.2.0'
   Visible = False
   object GroupBox1: TGroupBox
     Left = 10

+ 9 - 13
src/gui/wizards/UWIZSendPASC_Confirmation.pas

@@ -3,14 +3,10 @@ unit UWIZSendPASC_Confirmation;
 {$mode delphi}
 {$modeswitch nestedprocvars}
 
-{ Copyright (c) 2018 Sphere 10 Software (http://www.sphere10.com/)
+{ Copyright (c) 2018 by Ugochukwu Mmaduekwe
 
   Distributed under the MIT software license, see the accompanying file LICENSE
   or visit http://www.opensource.org/licenses/mit-license.php.
-
-  Acknowledgements:
-  Ugochukwu Mmaduekwe - main developer
-  Herman Schoenfeld - designer
 }
 
 interface
@@ -49,11 +45,11 @@ type
 
   TAccountSenderDataSource = class(TAccountsDataSourceBase)
     private
-      FModel : TWIZOperationsModel.TSendPASCModel;
+      FModel : TWIZOperationsModel;
     protected
       function GetColumns : TDataColumns; override;
     public
-      property Model : TWIZOperationsModel.TSendPASCModel read FModel write FModel;
+      property Model : TWIZOperationsModel read FModel write FModel;
       procedure FetchAll(const AContainer : TList<TAccount>); override;
       function GetItemField(constref AItem: TAccount; const ABindingName : AnsiString) : Variant; override;
   end;
@@ -94,10 +90,10 @@ begin
   end;
 
    data := TAccountSenderDataSource.Create(FSendersGrid);
-   data.Model := Model.SendPASCModel;
+   data.Model := Model;
    FSendersGrid.DataSource := data;
    paGrid.AddControlDockCenter(FSendersGrid);
-   lblSgnAcc.Caption := TAccountComp.AccountNumberToAccountTxtNumber(Model.SendPASCModel.SignerAccount.account);
+   lblSgnAcc.Caption := TAccountComp.AccountNumberToAccountTxtNumber(Model.SignerModel.SignerAccount.account);
    lblDestAcc.Caption := TAccountComp.AccountNumberToAccountTxtNumber(Model.SendPASCModel.DestinationAccount.account);
 end;
 
@@ -122,9 +118,9 @@ begin
    else if ABindingName = 'Balance' then
      Result := TAccountComp.FormatMoney(AItem.Balance)
    else if ABindingName = 'AmountToSend' then
-     Result := TAccountComp.FormatMoney(Model.SingleAmountToSend)
+     Result := Model.SendPASCModel.AmountToSend
      else if ABindingName = 'Fee' then
-     Result := TAccountComp.FormatMoney(Model.SingleOperationFee)
+     Result := TAccountComp.FormatMoney(Model.FeeModel.DefaultFee)
    else raise Exception.Create(Format('Field not found [%s]', [ABindingName]));
 end;
 
@@ -133,9 +129,9 @@ procedure TAccountSenderDataSource.FetchAll(const AContainer : TList<TAccount>);
 var
   i: Integer;
 begin
-  for i := Low(Model.SelectedAccounts) to High(Model.SelectedAccounts) do
+  for i := Low(Model.SendPASCModel.SelectedAccounts) to High(Model.SendPASCModel.SelectedAccounts) do
   begin
-    AContainer.Add( Model.SelectedAccounts[i] );
+    AContainer.Add( Model.SendPASCModel.SelectedAccounts[i] );
   end;
 end;
 

+ 32 - 0
src/gui/wizards/UWIZSendPASC_Start.lfm

@@ -0,0 +1,32 @@
+object WIZSendPASC_Start: TWIZSendPASC_Start
+  Left = 0
+  Height = 261
+  Top = 0
+  Width = 429
+  Caption = 'WIZSendPASC_Start'
+  ClientHeight = 261
+  ClientWidth = 429
+  LCLVersion = '1.8.2.0'
+  Visible = False
+  object gpSender: TGroupBox
+    Left = 4
+    Height = 256
+    Top = 0
+    Width = 420
+    Anchors = [akTop, akLeft, akRight, akBottom]
+    Caption = 'Sender Accounts'
+    ClientHeight = 236
+    ClientWidth = 416
+    TabOrder = 0
+    object paGrid: TPanel
+      Left = 8
+      Height = 192
+      Top = 24
+      Width = 400
+      Anchors = [akTop, akLeft, akRight, akBottom]
+      BevelOuter = bvNone
+      Caption = 'GRID PANEL'
+      TabOrder = 0
+    end
+  end
+end

+ 113 - 0
src/gui/wizards/UWIZSendPASC_Start.pas

@@ -0,0 +1,113 @@
+unit UWIZSendPASC_Start;
+
+{$mode delphi}
+
+{ Copyright (c) 2018 by Ugochukwu Mmaduekwe
+
+  Distributed under the MIT software license, see the accompanying file LICENSE
+  or visit http://www.opensource.org/licenses/mit-license.php.
+
+  Acknowledgements:
+    Herman Schoenfeld <[email protected]>: added grid-based layout
+
+}
+
+interface
+
+uses
+  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
+  ExtCtrls, UVisualGrid, UCommon.Data, UCellRenderers,
+  UWizard, UWIZSendPASC, UWIZSendPASC_Transaction, UWIZSendPASC_Confirmation, UWIZModels;
+
+type
+
+  { TWIZSendPASC_Start }
+
+  TWIZSendPASC_Start = class(TWizardForm<TWIZOperationsModel>)
+    gpSender: TGroupBox;
+    paGrid: TPanel;
+  private
+    FSendersGrid : TVisualGrid;
+  public
+    procedure OnPresent; override;
+    procedure OnNext; override;
+  end;
+
+
+
+implementation
+
+{$R *.lfm}
+
+uses UAccounts, UDataSources, UCommon, UCommon.UI, Generics.Collections;
+
+type
+
+  { TAccountSenderDataSource }
+
+  TAccountSenderDataSource = class(TAccountsDataSourceBase)
+    private
+      FModel : TWIZOperationsModel.TSendPASCModel;
+    public
+      property Model : TWIZOperationsModel.TSendPASCModel read FModel write FModel;
+      procedure FetchAll(const AContainer : TList<TAccount>); override;
+  end;
+
+{ TWIZSendPASC_Start }
+
+procedure TWIZSendPASC_Start.OnPresent;
+var
+  data : TAccountSenderDataSource;
+begin
+  FSendersGrid := TVisualGrid.Create(Self);
+  FSendersGrid.CanSearch:= False;
+  FSendersGrid.SortMode := smMultiColumn;
+  FSendersGrid.FetchDataInThread := False;
+  FSendersGrid.AutoPageSize := True;
+  FSendersGrid.SelectionType := stNone;
+  FSendersGrid.Options := [vgoColAutoFill, vgoColSizing, vgoSortDirectionAllowNone, vgoAutoHidePaging];
+  with FSendersGrid.AddColumn('Account') do begin
+    StretchedToFill := true;
+    Binding := 'AccountNumber';
+    SortBinding := 'AccountNumber';
+    DisplayBinding := 'Account';
+    Width := 100;
+    HeaderFontStyles := [fsBold];
+    DataFontStyles := [fsBold];
+    Filters:=SORTABLE_NUMERIC_FILTER;
+  end;
+  with FSendersGrid.AddColumn('Balance') do begin
+    Binding := 'BalanceDecimal';
+    SortBinding := 'Balance';
+    DisplayBinding := 'Balance';
+    Width := 100;
+    HeaderAlignment:=taRightJustify;
+    DataAlignment:=taRightJustify;
+    Renderer := TCellRenderers.PASC;
+    Filters:=SORTABLE_NUMERIC_FILTER;
+  end;
+  data := TAccountSenderDataSource.Create(FSendersGrid);
+  data.Model := Model.SendPASCModel;
+  FSendersGrid.DataSource := data;
+  paGrid.AddControlDockCenter(FSendersGrid);
+end;
+
+procedure TWIZSendPASC_Start.OnNext;
+begin
+  UpdatePath(ptReplaceAllNext, [TWIZSendPASC_Transaction, TWIZSendPASC_Confirmation]);
+end;
+
+{ TAccountSenderDataSource }
+
+procedure TAccountSenderDataSource.FetchAll(const AContainer : TList<TAccount>);
+var
+  i: Integer;
+begin
+  for i := Low(Model.SelectedAccounts) to High(Model.SelectedAccounts) do
+  begin
+    AContainer.Add( Model.SelectedAccounts[i] );
+  end;
+end;
+
+end.
+

+ 151 - 0
src/gui/wizards/UWIZSendPASC_Transaction.lfm

@@ -0,0 +1,151 @@
+object WIZSendPASC_Transaction: TWIZSendPASC_Transaction
+  Left = 0
+  Height = 253
+  Top = 0
+  Width = 429
+  ActiveControl = cbSignerAccount
+  Caption = 'WIZSendPASC_Transaction'
+  ClientHeight = 253
+  ClientWidth = 429
+  LCLVersion = '1.8.2.0'
+  Visible = False
+  object gbTransaction: TGroupBox
+    Left = 22
+    Height = 192
+    Top = 40
+    Width = 384
+    Caption = 'Transaction Details'
+    ClientHeight = 172
+    ClientWidth = 380
+    TabOrder = 0
+    object cbSignerAccount: TComboBox
+      Left = 8
+      Height = 23
+      Top = 8
+      Width = 168
+      ItemHeight = 15
+      Items.Strings = (
+        ''
+      )
+      OnChange = cbSignerAccountChange
+      TabOrder = 0
+      Text = 'Select Signer Account'
+    end
+    object lblBalance: TLabel
+      Left = 200
+      Height = 15
+      Top = 12
+      Width = 151
+      Caption = 'Please Select Signer Account'
+      Font.Color = clRed
+      ParentColor = False
+      ParentFont = False
+    end
+    object lblDestAcc: TLabel
+      Left = 8
+      Height = 15
+      Top = 48
+      Width = 108
+      Caption = 'Destination Account'
+      ParentColor = False
+    end
+    object edtDestAcc: TEdit
+      Left = 8
+      Height = 23
+      Top = 74
+      Width = 136
+      TabOrder = 1
+    end
+    object lblAmount: TLabel
+      Left = 8
+      Height = 15
+      Top = 116
+      Width = 44
+      Caption = 'Amount'
+      ParentColor = False
+    end
+    object edtAmt: TEdit
+      Left = 8
+      Height = 23
+      Top = 143
+      Width = 136
+      TabOrder = 2
+    end
+    object btnSearch: TSpeedButton
+      Left = 152
+      Height = 22
+      Top = 75
+      Width = 23
+      Glyph.Data = {
+        36040000424D3604000000000000360000002800000010000000100000000100
+        2000000000000004000064000000640000000000000000000000000000000000
+        0000000000000000000F00000010000000100000001000000010000000100000
+        001000000010000000100000000F000000000000000000000000000000003509
+        033190370DEBA6410FFFA6410FFFA6410FFFA6410FFFA6410FFFA6410FFFA641
+        0FFFA6410FFFA6410FFFA6410FFF90370DEB350903310000000000000000953A
+        0EE6B14B10FFB04B10FFB04B10FFB04B10FFB04B10FFB04B10FFB04B10FFB04B
+        10FFB14B11FFAE460CFFB14B11FFB14B10FF953A0EE60000000000000001AA47
+        12FFB24D11FFB24D11FFB24D11FFB24D11FFB34E12FFB34E12FFB24D11FFB34E
+        12FFAB440DFFE1C19FFFAC4914FFB34E12FFAA4712FF0000000100000001AD4A
+        13FFB65113FFB65113FFB55113FFB14A0EFFAA3F05FFAA3F05FFB14A0EFFAE48
+        0EFFEEDCBCFFFFFFE2FFE6C6A1FFB44E0FFFAD4A13FF0000000100000001AF4D
+        14FFB85414FFB85414FFB75A25FFE5C8A7FFFFFFEBFFFFFFEAFFE3C3A1FFECD7
+        B8FFFFFFE4FFF1DFBEFFB55011FFB85414FFAF4D14FF0000000100000001B251
+        15FFBB5816FFBB6027FFFFFFEAFFEBCFABFFCC814BFFCC824CFFECD1AEFFFFFF
+        E8FFEFDAB9FFB95412FFBB5816FFBB5816FFB25115FF0000000100000001B555
+        16FFBC5712FFEACDAAFFEBCEAAFFBB540EFFBF5E19FFBF5E19FFBB550FFFEDD2
+        B0FFE7C7A5FFBC5712FFBE5C16FFBE5C16FFB55516FF0000000100000001B859
+        19FFBD5915FFFFFFFCFFD08857FFC56B29FFC46B29FFC46A29FFC56B29FFD18B
+        5BFFFFFFF9FFBF5D1BFFC46A27FFC36623FFB85919FF0000000100000001C170
+        35FFC66B2BFFFFFFFFFFD38F64FFCB7839FFCA7739FFCA7739FFCB7839FFD492
+        67FFFFFFFFFFC66C2CFFCA7739FFCB7739FFC17035FF0000000100000001C77F
+        46FFCF8248FFF1DBCCFFEED3C5FFCC7A40FFD1864CFFD1864CFFCC7A40FFEFD5
+        C8FFF1D9C9FFCF8348FFD0864CFFD0864CFFC77F46FF0000000100000001CD8D
+        59FFD79561FFDA9D6EFFFFFFFFFFF0D7C8FFDA9F79FFDAA079FFF0D8CAFFFFFF
+        FFFFD99C6DFFD79561FFD69460FFD69460FFCD8D59FF0000000100000000D29A
+        6CFFDCA373FFDCA373FFDEA97FFFF5E5D8FFFFFFFFFFFFFFFFFFF5E5D7FFDEA9
+        7EFFDCA373FFDCA373FFDCA373FFDCA373FFD29A6CFF0000000000000000C99C
+        75E0E1AE83FFE1AE84FFE1AE84FFE0AC80FFDFA87AFFDEA87AFFE0AC80FFE1AE
+        84FFE1AE84FFE1AE84FFE1AE84FFE1AE83FFC99C75E000000000FFFFFE007960
+        4721D0AA87DCDCB58FFFDDB590FFDDB590FFDDB590FFDDB590FFDDB590FFDDB5
+        90FFDDB590FFDDB590FFDCB58FFFD0AA87DC79604821FFFFFA0000000000FFFF
+        FF00000000000000000000000000000000000000000000000000000000000000
+        000000000000000000000000000000000000FFFFFF0000000000
+      }
+      OnClick = btnSearchClick
+    end
+    object edtOpFee: TEdit
+      Left = 232
+      Height = 23
+      Top = 144
+      Width = 136
+      TabOrder = 3
+    end
+    object lblOpFee: TLabel
+      Left = 232
+      Height = 15
+      Top = 116
+      Width = 74
+      Caption = 'Operation Fee'
+      ParentColor = False
+    end
+  end
+  object lblTotalBalances: TLabel
+    Left = 24
+    Height = 15
+    Top = 16
+    Width = 176
+    Caption = 'Selected Accounts Total Balance: '
+    ParentColor = False
+  end
+  object lblTotalBalanceValue: TLabel
+    Left = 208
+    Height = 15
+    Top = 16
+    Width = 70
+    Caption = 'Total Balance'
+    Font.Color = clGreen
+    ParentColor = False
+    ParentFont = False
+  end
+end

+ 258 - 0
src/gui/wizards/UWIZSendPASC_Transaction.pas

@@ -0,0 +1,258 @@
+unit UWIZSendPASC_Transaction;
+
+{$mode delphi}
+{$modeswitch nestedprocvars}
+
+{ Copyright (c) 2018 by Ugochukwu Mmaduekwe
+
+  Distributed under the MIT software license, see the accompanying file LICENSE
+  or visit http://www.opensource.org/licenses/mit-license.php.
+}
+
+interface
+
+uses
+  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
+  ExtCtrls, Buttons, UCommon, UCommon.Collections, UWallet,
+  UFRMAccountSelect, UNode, UWizard, UWIZSendPASC, UWIZSendPASC_Confirmation, UWIZSendPASC_TransactionPayload, UWIZModels;
+
+type
+
+  { TWIZSendPASC_Transaction }
+
+  TWIZSendPASC_Transaction = class(TWizardForm<TWIZOperationsModel>)
+    cbSignerAccount: TComboBox;
+    edtOpFee: TEdit;
+    edtAmt: TEdit;
+    edtDestAcc: TEdit;
+    gbTransaction: TGroupBox;
+    lblOpFee: TLabel;
+    lblAmount: TLabel;
+    lblDestAcc: TLabel;
+    lblTotalBalanceValue: TLabel;
+    lblTotalBalances: TLabel;
+    lblBalance: TLabel;
+    btnSearch: TSpeedButton;
+    procedure btnSearchClick(Sender: TObject);
+    procedure cbSignerAccountChange(Sender: TObject);
+
+  public
+    procedure OnPresent; override;
+    procedure OnNext; override;
+    function Validate(out message: ansistring): boolean; override;
+  end;
+
+
+implementation
+
+{$R *.lfm}
+
+uses
+  UAccounts, UUserInterface, USettings;
+
+{ TWIZSendPASC_Transaction }
+
+procedure TWIZSendPASC_Transaction.cbSignerAccountChange(Sender: TObject);
+begin
+  if cbSignerAccount.ItemIndex < 1 then
+  begin
+    lblBalance.Font.Color := clRed;
+    lblBalance.Caption := 'Please Select Signer Account';
+  end
+  else
+  begin
+    lblBalance.Font.Color := clGreen;
+    lblBalance.Caption := Format('%s PASC',
+      [TAccountComp.FormatMoney(Model.SendPASCModel.SelectedAccounts[PtrInt(
+      cbSignerAccount.Items.Objects[cbSignerAccount.ItemIndex])].Balance)]);
+  end;
+end;
+
+procedure TWIZSendPASC_Transaction.btnSearchClick(Sender: TObject);
+var
+  F: TFRMAccountSelect;
+  c: cardinal;
+begin
+  F := TFRMAccountSelect.Create(Self);
+  F.Position := poMainFormCenter;
+  try
+    F.Node := TNode.Node;
+    F.WalletKeys := TWallet.Keys;
+    F.Filters := edtDestAcc.Tag;
+    if TAccountComp.AccountTxtNumberToAccountNumber(edtDestAcc.Text, c) then
+      F.DefaultAccount := c;
+    F.AllowSelect := True;
+    if F.ShowModal = mrOk then
+    begin
+      edtDestAcc.Text := TAccountComp.AccountNumberToAccountTxtNumber(F.GetSelected);
+    end;
+  finally
+    F.Free;
+  end;
+end;
+
+procedure TWIZSendPASC_Transaction.OnPresent;
+
+  function GetAccNoWithChecksum(AAccountNumber: cardinal): string;
+  begin
+    Result := TAccountComp.AccountNumberToAccountTxtNumber(AAccountNumber);
+  end;
+
+var
+  acc: TAccount;
+  accNumberwithChecksum: string;
+  totalBalance: int64;
+  i: integer;
+begin
+  cbSignerAccount.Items.BeginUpdate;
+  totalBalance := 0;
+  try
+    cbSignerAccount.Items.Clear;
+    cbSignerAccount.Items.Add('Select Signer Account');
+    for i := 0 to High(Model.SendPASCModel.SelectedAccounts) do
+    begin
+      acc := Model.SendPASCModel.SelectedAccounts[i];
+      accNumberwithChecksum := GetAccNoWithChecksum(acc.account);
+      totalBalance := totalBalance + acc.balance;
+      cbSignerAccount.Items.AddObject(accNumberwithChecksum, TObject(i));
+    end;
+  finally
+    cbSignerAccount.Items.EndUpdate;
+  end;
+  cbSignerAccount.ItemIndex := Model.SendPASCModel.SelectedIndex;
+  cbSignerAccountChange(Self);
+  lblTotalBalanceValue.Caption :=
+    Format('%s PASC', [TAccountComp.FormatMoney(totalBalance)]);
+
+  if Length(Model.SendPASCModel.SelectedAccounts) > 1 then
+  begin
+    edtAmt.Text := 'ALL BALANCE';
+    edtAmt.Enabled := False;
+  end
+  else
+  begin
+    edtAmt.Text := TAccountComp.FormatMoney(0);
+  end;
+  edtOpFee.Text := TAccountComp.FormatMoney(TSettings.DefaultFee);
+end;
+
+procedure TWIZSendPASC_Transaction.OnNext;
+
+  function GetAccNoWithoutChecksum(const AAccount: string): cardinal;
+  begin
+    if not TAccountComp.AccountTxtNumberToAccountNumber(AAccount, Result) then
+    begin
+      raise Exception.Create(
+        'Internal Error: Unable to parse account number from input');
+    end;
+  end;
+
+  function GetAccounts(AccountNumber: cardinal): TAccount;
+  var
+    acc: TAccount;
+    safeBox: TPCSafeBox;
+    keys: TOrderedAccountKeysList;
+    i: integer;
+  begin
+    keys := TWallet.keys.AccountsKeyList;
+    safeBox := TUserInterface.Node.Bank.safeBox;
+    safeBox.StartThreadSafe;
+    try
+      acc := safeBox.Account(AccountNumber);
+      if keys.IndexOfAccountKey(acc.accountInfo.accountKey) >= 0 then
+      begin
+        Result := acc;
+      end;
+    finally
+      safeBox.EndThreadSave;
+    end;
+
+  end;
+
+begin
+  Model.SendPASCModel.SelectedIndex := cbSignerAccount.ItemIndex;
+  Model.SignerModel.SignerAccount := Model.SendPASCModel.SelectedAccounts[PtrInt(cbSignerAccount.Items.Objects[cbSignerAccount.ItemIndex])];
+  Model.SendPASCModel.DestinationAccount := GetAccounts(GetAccNoWithoutChecksum(edtDestAcc.Text));
+  Model.SendPASCModel.AmountToSend := edtAmt.Text;
+  UpdatePath(ptReplaceAllNext, [TWIZSendPASC_TransactionPayload, TWIZSendPASC_Confirmation]);
+end;
+
+function TWIZSendPASC_Transaction.Validate(out message: ansistring): boolean;
+
+  function GetAccNoWithChecksum(constref AAccount: TAccount): string;
+  begin
+    Result := TAccountComp.AccountNumberToAccountTxtNumber(AAccount.account);
+  end;
+
+var
+  AccountNumbersWithChecksum: TArray<string>;
+  Accounts: TArray<TAccount>;
+  c: cardinal;
+  DestAccount: TAccount;
+  amount, opfee: int64;
+  i: integer;
+begin
+  Accounts := Model.SendPASCModel.SelectedAccounts;
+  Result := True;
+  if cbSignerAccount.ItemIndex < 1 then
+  begin
+    message := 'A signer account must be selected';
+    Result := False;
+    Exit;
+  end;
+
+  if not (TAccountComp.AccountTxtNumberToAccountNumber(edtDestAcc.Text, c)) then
+  begin
+    message := 'Invalid destination account (' + edtDestAcc.Text + ')';
+    Result := False;
+    Exit;
+  end;
+
+  if (c < 0) or (c >= TNode.Node.Bank.AccountsCount) then
+  begin
+    message := 'Invalid destination account (' +
+      TAccountComp.AccountNumberToAccountTxtNumber(c) + ')';
+    Result := False;
+    Exit;
+  end;
+
+  DestAccount := TNode.Node.Operations.SafeBoxTransaction.account(c);
+  if Length(Accounts) = 1 then
+  begin
+    if not TAccountComp.TxtToMoney(edtAmt.Text, amount) then
+    begin
+      message := 'Invalid amount (' + edtAmt.Text + ')';
+      Result := False;
+      Exit;
+    end;
+  end;
+
+  AccountNumbersWithChecksum := TListTool<TAccount, string>.Transform(Accounts, GetAccNoWithCheckSum);
+
+  if TArrayTool<string>.Contains(AccountNumbersWithChecksum, edtDestAcc.Text) then
+  begin
+    message := 'Sender and destination account are the same';
+    Result := False;
+    Exit;
+  end;
+
+  if not TAccountComp.TxtToMoney(Trim(edtOpFee.Text), Model.FeeModel.DefaultFee) then
+  begin
+    message := 'Invalid fee value "' + edtOpFee.Text + '"';
+    Result := False;
+    Exit;
+  end;
+
+  //for i := Low(Accounts) to High(Accounts) do
+  //begin
+  //  if (Accounts[i].balance < (amount + opfee)) then
+  //  begin
+  //    message := 'Insufficient funds';
+  //    Result := False;
+  //    Exit;
+  //  end;
+  //end;
+
+end;
+
+end.

+ 98 - 0
src/gui/wizards/UWIZSendPASC_TransactionPayload.lfm

@@ -0,0 +1,98 @@
+object WIZSendPASC_TransactionPayload: TWIZSendPASC_TransactionPayload
+  Left = 0
+  Height = 253
+  Top = 0
+  Width = 429
+  ActiveControl = mmoPayload
+  Caption = 'Form1'
+  ClientHeight = 253
+  ClientWidth = 429
+  LCLVersion = '1.8.2.0'
+  Visible = False
+  object grpPayload: TGroupBox
+    Left = 8
+    Height = 244
+    Top = 2
+    Width = 416
+    Anchors = [akTop, akLeft, akRight, akBottom]
+    Caption = 'Transaction Payload'
+    ClientHeight = 224
+    ClientWidth = 412
+    TabOrder = 0
+    object paPayload: TPanel
+      Left = 8
+      Height = 214
+      Top = 2
+      Width = 396
+      Anchors = [akTop, akLeft, akRight, akBottom]
+      BevelOuter = bvNone
+      ClientHeight = 214
+      ClientWidth = 396
+      TabOrder = 0
+      object mmoPayload: TMemo
+        Left = 0
+        Height = 70
+        Top = 136
+        Width = 386
+        TabOrder = 0
+      end
+      object Label1: TLabel
+        Left = 0
+        Height = 15
+        Top = 118
+        Width = 69
+        Caption = 'Payload Data'
+        ParentColor = False
+      end
+      object rbEncryptedWithOldEC: TRadioButton
+        Left = 3
+        Height = 19
+        Top = 0
+        Width = 194
+        Caption = 'Encrypted with sender public key'
+        TabOrder = 1
+      end
+      object rbEncryptedWithEC: TRadioButton
+        Left = 3
+        Height = 19
+        Top = 24
+        Width = 227
+        Caption = 'Encrypted with dest account public key'
+        Checked = True
+        TabOrder = 2
+        TabStop = True
+      end
+      object rbEncryptedWithPassword: TRadioButton
+        Left = 3
+        Height = 19
+        Top = 48
+        Width = 152
+        Caption = 'Encrypted with password'
+        TabOrder = 3
+      end
+      object lblPassword: TLabel
+        Left = 3
+        Height = 15
+        Top = 73
+        Width = 53
+        Caption = 'Password:'
+        ParentColor = False
+      end
+      object rbNotEncrypted: TRadioButton
+        Left = 3
+        Height = 19
+        Top = 94
+        Width = 181
+        Caption = 'Don''t encrypt (public payload)'
+        TabOrder = 4
+      end
+      object edtPassword: TEdit
+        Left = 64
+        Height = 23
+        Top = 70
+        Width = 160
+        TabOrder = 5
+      end
+    end
+  end
+end

+ 84 - 0
src/gui/wizards/UWIZSendPASC_TransactionPayload.pas

@@ -0,0 +1,84 @@
+unit UWIZSendPASC_TransactionPayload;
+
+{$mode delphi}
+{$modeswitch nestedprocvars}
+
+{ Copyright (c) 2018 by Ugochukwu Mmaduekwe
+
+  Distributed under the MIT software license, see the accompanying file LICENSE
+  or visit http://www.opensource.org/licenses/mit-license.php.
+}
+
+interface
+
+uses
+  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
+  ExtCtrls, Buttons, UCommon, UCommon.Collections,
+  UWizard, UWIZSendPASC, UWIZModels;
+
+type
+
+  { TWIZSendPASC_TransactionPayload }
+
+  TWIZSendPASC_TransactionPayload = class(TWizardForm<TWIZOperationsModel>)
+    edtPassword: TEdit;
+    grpPayload: TGroupBox;
+    Label1: TLabel;
+    lblPassword: TLabel;
+    mmoPayload: TMemo;
+    paPayload: TPanel;
+    rbEncryptedWithOldEC: TRadioButton;
+    rbEncryptedWithEC: TRadioButton;
+    rbEncryptedWithPassword: TRadioButton;
+    rbNotEncrypted: TRadioButton;
+  public
+    procedure OnNext; override;
+    function Validate(out message: ansistring): boolean; override;
+  end;
+
+
+implementation
+
+{$R *.lfm}
+
+uses
+  UAccounts, UUserInterface;
+
+{ TWIZSendPASC_TransactionPayload }
+
+procedure TWIZSendPASC_TransactionPayload.OnNext;
+begin
+  Model.PayloadModel.Payload := mmoPayload.Lines.Text;
+  if rbEncryptedWithOldEC.Checked then
+  begin
+    Model.PayloadModel.PayloadEncryptionMode := akaEncryptWithOldEC;
+  end
+  else
+  if rbEncryptedWithEC.Checked then
+  begin
+    Model.PayloadModel.PayloadEncryptionMode := akaEncryptWithEC;
+  end
+  else
+  if rbEncryptedWithPassword.Checked then
+  begin
+    Model.PayloadModel.PayloadEncryptionMode := akaEncryptWithPassword;
+  end
+  else
+  if rbNotEncrypted.Checked then
+  begin
+    Model.PayloadModel.PayloadEncryptionMode := akaNotEncrypt;
+  end;
+end;
+
+function TWIZSendPASC_TransactionPayload.Validate(out message: ansistring): boolean;
+begin
+  if (not rbNotEncrypted.Checked) and (not rbEncryptedWithEC.Checked) and
+    (not rbEncryptedWithOldEC.Checked) and (not rbEncryptedWithPassword.Checked) then
+  begin
+    message := 'you must select an encryption option for payload';
+    Result := False;
+    Exit;
+  end;
+end;
+
+end.

+ 14 - 14
src/gui/wizards/UWIZTransferAccount.pas

@@ -55,9 +55,9 @@ var
 begin
   valid := False;
   payload_encrypted := '';
-  Model.TransferAccountModel.EncodedPayload := '';
+  Model.PayloadModel.EncodedPayload := '';
   errors := 'Unknown error';
-  payload_u := Model.TransferAccountModel.Payload;
+  payload_u := Model.PayloadModel.Payload;
 
   try
     if (payload_u = '') then
@@ -65,9 +65,9 @@ begin
       valid := True;
       Exit;
     end;
-    case Model.TransferAccountModel.PayloadEncryptionMode of
+    case Model.PayloadModel.PayloadEncryptionMode of
 
-      akaEncryptWithSender:
+      akaEncryptWithOldEC:
       begin
         // Use sender
         errors := 'Error encrypting';
@@ -76,7 +76,7 @@ begin
         valid := payload_encrypted <> '';
       end;
 
-      akaEncryptWithReceiver:
+      akaEncryptWithEC:
       begin
         errors := 'Public key: ' + 'Error encrypting';
 
@@ -97,7 +97,7 @@ begin
       akaEncryptWithPassword:
       begin
         payload_encrypted := TAESComp.EVP_Encrypt_AES256(
-          payload_u, Model.TransferAccountModel.EncryptionPassword);
+          payload_u, Model.PayloadModel.EncryptionPassword);
         valid := payload_encrypted <> '';
       end;
 
@@ -124,7 +124,7 @@ begin
       end;
 
     end;
-    Model.TransferAccountModel.EncodedPayload := payload_encrypted;
+    Model.PayloadModel.EncodedPayload := payload_encrypted;
     Result := valid;
   end;
 
@@ -206,7 +206,7 @@ begin
     if TNode.Node.Bank.SafeBox.CurrentProtocol >= 1 then
     begin
       // Signer:
-      SignerAccount := Model.TransferAccountModel.SignerAccount;
+      SignerAccount := Model.SignerModel.SignerAccount;
       if (TAccountComp.IsAccountLocked(SignerAccount.accountInfo,
         TNode.Node.Bank.BlocksCount)) then
       begin
@@ -289,8 +289,8 @@ begin
       wk := TWallet.Keys.Key[i];
       dooperation := True;
       // Default fee
-      if account.balance > uint64(Model.TransferAccountModel.DefaultFee) then
-        _fee := Model.TransferAccountModel.DefaultFee
+      if account.balance > uint64(Model.FeeModel.DefaultFee) then
+        _fee := Model.FeeModel.DefaultFee
       else
         _fee := account.balance;
 
@@ -314,20 +314,20 @@ begin
         if uint64(_totalSignerFee) >= signerAccount.balance then
           _fee := 0
         else if signerAccount.balance - uint64(_totalSignerFee) >
-          uint64(Model.TransferAccountModel.DefaultFee) then
-          _fee := Model.TransferAccountModel.DefaultFee
+          uint64(Model.FeeModel.DefaultFee) then
+          _fee := Model.FeeModel.DefaultFee
         else
           _fee := signerAccount.balance - uint64(_totalSignerFee);
         op := TOpChangeKeySigned.Create(signerAccount.account,
           signerAccount.n_operation + _signer_n_ops + 1, account.account,
-          wk.PrivateKey, _newOwnerPublicKey, _fee, Model.TransferAccountModel.EncodedPayload);
+          wk.PrivateKey, _newOwnerPublicKey, _fee, Model.PayloadModel.EncodedPayload);
         Inc(_signer_n_ops);
         Inc(_totalSignerFee, _fee);
       end
       else
       begin
         op := TOpChangeKey.Create(account.account, account.n_operation +
-          1, account.account, wk.PrivateKey, _newOwnerPublicKey, _fee, Model.TransferAccountModel.EncodedPayload);
+          1, account.account, wk.PrivateKey, _newOwnerPublicKey, _fee, Model.PayloadModel.EncodedPayload);
       end;
       Inc(_totalfee, _fee);
       operationstxt :=

+ 8 - 8
src/gui/wizards/UWIZTransferAccount_Confirmation.pas

@@ -43,11 +43,11 @@ type
 
   TAccountSenderDataSource = class(TAccountsDataSourceBase)
     private
-      FModel : TWIZOperationsModel.TTransferAccountModel;
+      FModel : TWIZOperationsModel;
     protected
       function GetColumns : TDataColumns; override;
     public
-      property Model : TWIZOperationsModel.TTransferAccountModel read FModel write FModel;
+      property Model : TWIZOperationsModel read FModel write FModel;
       procedure FetchAll(const AContainer : TList<TAccount>); override;
       function GetItemField(constref AItem: TAccount; const ABindingName : AnsiString) : Variant; override;
   end;
@@ -88,10 +88,10 @@ begin
   end;
 
    data := TAccountSenderDataSource.Create(FSendersGrid);
-   data.Model := Model.TransferAccountModel;
+   data.Model := Model;
    FSendersGrid.DataSource := data;
    paGrid.AddControlDockCenter(FSendersGrid);
-   lblSgnAcc.Caption := TAccountComp.AccountNumberToAccountTxtNumber(Model.TransferAccountModel.SignerAccount.account);
+   lblSgnAcc.Caption := TAccountComp.AccountNumberToAccountTxtNumber(Model.SignerModel.SignerAccount.account);
 end;
 
 { TAccountSenderDataSource }
@@ -115,9 +115,9 @@ begin
    else if ABindingName = 'CurrentPublicKey' then
      Result := TAccountComp.AccountPublicKeyExport(AItem.accountInfo.accountKey)
    else if ABindingName = 'NewPublicKey' then
-     Result := Model.NewPublicKey
+     Result := Model.TransferAccountModel.NewPublicKey
      else if ABindingName = 'Fee' then
-     Result := TAccountComp.FormatMoney(Model.DefaultFee)
+     Result := TAccountComp.FormatMoney(Model.FeeModel.DefaultFee)
    else raise Exception.Create(Format('Field not found [%s]', [ABindingName]));
 end;
 
@@ -126,9 +126,9 @@ procedure TAccountSenderDataSource.FetchAll(const AContainer : TList<TAccount>);
 var
   i: Integer;
 begin
-  for i := Low(Model.SelectedAccounts) to High(Model.SelectedAccounts) do
+  for i := Low(Model.TransferAccountModel.SelectedAccounts) to High(Model.TransferAccountModel.SelectedAccounts) do
   begin
-    AContainer.Add( Model.SelectedAccounts[i] );
+    AContainer.Add( Model.TransferAccountModel.SelectedAccounts[i] );
   end;
 end;
 

+ 2 - 2
src/gui/wizards/UWIZTransferAccount_Transaction.pas

@@ -104,7 +104,7 @@ end;
 procedure TWIZTransferAccount_Transaction.OnNext;
 begin
   Model.TransferAccountModel.SelectedIndex := cbSignerAccount.ItemIndex;
-  Model.TransferAccountModel.SignerAccount := Model.TransferAccountModel.SelectedAccounts[PtrInt(
+  Model.SignerModel.SignerAccount := Model.TransferAccountModel.SelectedAccounts[PtrInt(
     cbSignerAccount.Items.Objects[cbSignerAccount.ItemIndex])];
   Model.TransferAccountModel.NewPublicKey := Trim(edtPublicKey.Text);
 
@@ -124,7 +124,7 @@ begin
     Exit;
   end;
 
-  if not TAccountComp.TxtToMoney(Trim(edtOpFee.Text), Model.TransferAccountModel.DefaultFee) then
+  if not TAccountComp.TxtToMoney(Trim(edtOpFee.Text), Model.FeeModel.DefaultFee) then
   begin
     message := 'Invalid fee value "' + edtOpFee.Text + '"';
     Result := False;

+ 1 - 1
src/gui/wizards/UWIZTransferAccount_TransactionPayload.lfm

@@ -7,7 +7,7 @@ object WIZTransferAccount_TransactionPayload: TWIZTransferAccount_TransactionPay
   Caption = 'Form1'
   ClientHeight = 253
   ClientWidth = 429
-  LCLVersion = '1.8.1.0'
+  LCLVersion = '1.8.2.0'
   Visible = False
   object grpPayload: TGroupBox
     Left = 8

+ 5 - 5
src/gui/wizards/UWIZTransferAccount_TransactionPayload.pas

@@ -48,25 +48,25 @@ uses
 
 procedure TWIZTransferAccount_TransactionPayload.OnNext;
 begin
-  Model.TransferAccountModel.Payload := mmoPayload.Lines.Text;
+  Model.PayloadModel.Payload := mmoPayload.Lines.Text;
   if rbEncryptedWithOldEC.Checked then
   begin
-    Model.TransferAccountModel.PayloadEncryptionMode := akaEncryptWithSender;
+    Model.PayloadModel.PayloadEncryptionMode := akaEncryptWithOldEC;
   end
   else
   if rbEncryptedWithEC.Checked then
   begin
-    Model.TransferAccountModel.PayloadEncryptionMode := akaEncryptWithReceiver;
+    Model.PayloadModel.PayloadEncryptionMode := akaEncryptWithEC;
   end
   else
   if rbEncryptedWithPassword.Checked then
   begin
-    Model.TransferAccountModel.PayloadEncryptionMode := akaEncryptWithPassword;
+    Model.PayloadModel.PayloadEncryptionMode := akaEncryptWithPassword;
   end
   else
   if rbNotEncrypted.Checked then
   begin
-    Model.TransferAccountModel.PayloadEncryptionMode := akaNotEncrypt;
+    Model.PayloadModel.PayloadEncryptionMode := akaNotEncrypt;
   end;
 end;
 

+ 44 - 118
src/pascalcoin_wallet.lpi

@@ -33,7 +33,7 @@
         <PackageName Value="LCL"/>
       </Item1>
     </RequiredPackages>
-    <Units Count="100">
+    <Units Count="89">
       <Unit0>
         <Filename Value="pascalcoin_wallet.dpr"/>
         <IsPartOfProject Value="True"/>
@@ -372,211 +372,137 @@
         <IsPartOfProject Value="True"/>
       </Unit64>
       <Unit65>
-        <Filename Value="gui\wizards\UWIZSendPASC_ConfirmSender.pas"/>
+        <Filename Value="gui\wizards\UWIZSendPASC_Confirmation.pas"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZSendPASC_ConfirmSender"/>
+        <ComponentName Value="WIZSendPASC_Confirmation"/>
         <HasResources Value="True"/>
         <ResourceBaseClass Value="Form"/>
       </Unit65>
       <Unit66>
-        <Filename Value="gui\wizards\UWIZSendPASC_EnterRecipient.pas"/>
+        <Filename Value="gui\wizards\UWIZSendPASC_Start.pas"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZSendPASC_EnterRecipient"/>
+        <ComponentName Value="WIZSendPASC_Start"/>
         <HasResources Value="True"/>
         <ResourceBaseClass Value="Form"/>
       </Unit66>
       <Unit67>
-        <Filename Value="libraries\sphere10\UMemory.pas"/>
+        <Filename Value="gui\wizards\UWIZSendPASC_Transaction.pas"/>
         <IsPartOfProject Value="True"/>
+        <ComponentName Value="WIZSendPASC_Transaction"/>
+        <HasResources Value="True"/>
+        <ResourceBaseClass Value="Form"/>
       </Unit67>
       <Unit68>
-        <Filename Value="gui\UCellRenderers.pas"/>
+        <Filename Value="libraries\sphere10\UMemory.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit68>
       <Unit69>
-        <Filename Value="libraries\generics.collections\inc\generics.dictionaries.inc"/>
+        <Filename Value="gui\UCellRenderers.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit69>
       <Unit70>
-        <Filename Value="libraries\pascalcoin\UAppParams.pas"/>
+        <Filename Value="libraries\generics.collections\inc\generics.dictionaries.inc"/>
         <IsPartOfProject Value="True"/>
       </Unit70>
       <Unit71>
-        <Filename Value="libraries\pascalcoin\UFolderHelper.pas"/>
+        <Filename Value="libraries\pascalcoin\UAppParams.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit71>
       <Unit72>
-        <Filename Value="libraries\pascalcoin\UGridUtils.pas"/>
+        <Filename Value="libraries\pascalcoin\UFolderHelper.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit72>
       <Unit73>
-        <Filename Value="libraries\pascalcoin\UJSONFunctions.pas"/>
+        <Filename Value="libraries\pascalcoin\UGridUtils.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit73>
       <Unit74>
-        <Filename Value="core.utils\UCoreUtils.pas"/>
+        <Filename Value="libraries\pascalcoin\UJSONFunctions.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit74>
       <Unit75>
-        <Filename Value="core.utils\UDataSources.pas"/>
+        <Filename Value="core.utils\UCoreUtils.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit75>
       <Unit76>
-        <Filename Value="gui\wizards\UWIZTransferAccount.pas"/>
+        <Filename Value="core.utils\UDataSources.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit76>
       <Unit77>
-        <Filename Value="gui\wizards\UWIZTransferAccount_Start.pas"/>
+        <Filename Value="gui\wizards\UWIZSendPASC_TransactionPayload.pas"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZTransferAccount_Start"/>
+        <ComponentName Value="WIZSendPASC_TransactionPayload"/>
         <HasResources Value="True"/>
         <ResourceBaseClass Value="Form"/>
       </Unit77>
       <Unit78>
-        <Filename Value="gui\wizards\UWIZTransferAccount_Transaction.pas"/>
+        <Filename Value="gui\wizards\UWIZTransferAccount.pas"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZTransferAccount_Transaction"/>
-        <HasResources Value="True"/>
-        <ResourceBaseClass Value="Form"/>
       </Unit78>
       <Unit79>
-        <Filename Value="gui\wizards\UWIZTransferAccount_Confirmation.pas"/>
+        <Filename Value="gui\wizards\UWIZTransferAccount_Start.pas"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZTransferAccount_Confirmation"/>
+        <ComponentName Value="WIZTransferAccount_Start"/>
         <HasResources Value="True"/>
         <ResourceBaseClass Value="Form"/>
       </Unit79>
       <Unit80>
-        <Filename Value="gui\wizards\UWIZTransferAccount_TransactionPayload.pas"/>
+        <Filename Value="gui\wizards\UWIZTransferAccount_Transaction.pas"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZTransferAccount_TransactionPayload"/>
+        <ComponentName Value="WIZTransferAccount_Transaction"/>
         <HasResources Value="True"/>
         <ResourceBaseClass Value="Form"/>
       </Unit80>
       <Unit81>
-        <Filename Value="gui\wizards\UWIZChangeAccountPrivateKey.pas"/>
+        <Filename Value="gui\wizards\UWIZTransferAccount_Confirmation.pas"/>
         <IsPartOfProject Value="True"/>
+        <ComponentName Value="WIZTransferAccount_Confirmation"/>
+        <HasResources Value="True"/>
+        <ResourceBaseClass Value="Form"/>
       </Unit81>
       <Unit82>
-        <Filename Value="gui\wizards\UWIZChangeAccountPrivateKey_Confirmation.pas"/>
+        <Filename Value="gui\wizards\UWIZTransferAccount_TransactionPayload.pas"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZChangeAccountPrivateKey_Confirmation"/>
+        <ComponentName Value="WIZTransferAccount_TransactionPayload"/>
         <HasResources Value="True"/>
         <ResourceBaseClass Value="Form"/>
       </Unit82>
       <Unit83>
-        <Filename Value="gui\wizards\UWIZChangeAccountPrivateKey_Start.pas"/>
+        <Filename Value="gui\wizards\UWIZChangeAccountPrivateKey.pas"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZChangeAccountPrivateKey_Start"/>
-        <HasResources Value="True"/>
-        <ResourceBaseClass Value="Form"/>
       </Unit83>
       <Unit84>
-        <Filename Value="gui\wizards\UWIZChangeAccountPrivateKey_Transaction.pas"/>
+        <Filename Value="gui\wizards\UWIZChangeAccountPrivateKey_Confirmation.pas"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZChangeAccountPrivateKey_Transaction"/>
+        <ComponentName Value="WIZChangeAccountPrivateKey_Confirmation"/>
         <HasResources Value="True"/>
         <ResourceBaseClass Value="Form"/>
       </Unit84>
       <Unit85>
-        <Filename Value="gui\wizards\UWIZChangeAccountPrivateKey_TransactionPayload.pas"/>
+        <Filename Value="gui\wizards\UWIZChangeAccountPrivateKey_Start.pas"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZChangeAccountPrivateKey_TransactionPayload"/>
+        <ComponentName Value="WIZChangeAccountPrivateKey_Start"/>
         <HasResources Value="True"/>
         <ResourceBaseClass Value="Form"/>
       </Unit85>
       <Unit86>
-        <Filename Value="gui\wizards\UWIZEnlistAccountForSale.pas"/>
+        <Filename Value="gui\wizards\UWIZChangeAccountPrivateKey_Transaction.pas"/>
         <IsPartOfProject Value="True"/>
+        <ComponentName Value="WIZChangeAccountPrivateKey_Transaction"/>
+        <HasResources Value="True"/>
+        <ResourceBaseClass Value="Form"/>
       </Unit86>
       <Unit87>
-        <Filename Value="gui\wizards\UWIZEnlistAccountForSale_Confirmation.pas"/>
+        <Filename Value="gui\wizards\UWIZChangeAccountPrivateKey_TransactionPayload.pas"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZEnlistAccountForSale_Confirmation"/>
+        <ComponentName Value="WIZChangeAccountPrivateKey_TransactionPayload"/>
         <HasResources Value="True"/>
         <ResourceBaseClass Value="Form"/>
       </Unit87>
       <Unit88>
-        <Filename Value="gui\wizards\UWIZEnlistAccountForSale_Start.pas"/>
-        <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZEnlistAccountForSale_Start"/>
-        <HasResources Value="True"/>
-        <ResourceBaseClass Value="Form"/>
-      </Unit88>
-      <Unit89>
-        <Filename Value="gui\wizards\UWIZEnlistAccountForSale_Transaction.pas"/>
-        <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZEnlistAccountForSale_Transaction"/>
-        <HasResources Value="True"/>
-        <ResourceBaseClass Value="Form"/>
-      </Unit89>
-      <Unit90>
-        <Filename Value="gui\wizards\UWIZEnlistAccountForSale_TransactionPayload.pas"/>
-        <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZEnlistAccountForSale_TransactionPayload"/>
-        <HasResources Value="True"/>
-        <ResourceBaseClass Value="Form"/>
-      </Unit90>
-      <Unit91>
-        <Filename Value="gui\wizards\UWIZEnlistAccountForSale_List.pas"/>
-        <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZEnlistAccountForSale_List"/>
-        <HasResources Value="True"/>
-        <ResourceBaseClass Value="Form"/>
-      </Unit91>
-      <Unit92>
-        <Filename Value="gui\wizards\UWIZEnlistAccountForSale_PrivateSaleConfig.pas"/>
-        <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZEnlistAccountForSale_PrivateSaleConfig"/>
-        <HasResources Value="True"/>
-        <ResourceBaseClass Value="Form"/>
-      </Unit92>
-      <Unit93>
-        <Filename Value="gui\wizards\UWIZSendPASC_EnterQuantity.pas"/>
-        <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZSendPASC_EnterQuantity"/>
-        <HasResources Value="True"/>
-        <ResourceBaseClass Value="Form"/>
-      </Unit93>
-      <Unit94>
-        <Filename Value="gui\wizards\generic wizards\UWIZFeeOverride.pas"/>
-        <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZFeeOverride"/>
-        <HasResources Value="True"/>
-        <ResourceBaseClass Value="Form"/>
-      </Unit94>
-      <Unit95>
-        <Filename Value="gui\wizards\generic wizards\UWIZPayloadOverride.pas"/>
-        <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZPayloadOverride"/>
-        <HasResources Value="True"/>
-        <ResourceBaseClass Value="Form"/>
-      </Unit95>
-      <Unit96>
-        <Filename Value="gui\wizards\generic wizards\UWIZPayloadContentOverride.pas"/>
-        <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZPayloadContentOverride"/>
-        <HasResources Value="True"/>
-        <ResourceBaseClass Value="Form"/>
-      </Unit96>
-      <Unit97>
-        <Filename Value="gui\wizards\generic wizards\UWIZPayloadPasswordOverride.pas"/>
-        <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZPayloadPasswordOverride"/>
-        <HasResources Value="True"/>
-        <ResourceBaseClass Value="Form"/>
-      </Unit97>
-      <Unit98>
-        <Filename Value="gui\wizards\generic wizards\UWIZSelectSignerOverride.pas"/>
-        <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZSelectSignerOverride"/>
-        <HasResources Value="True"/>
-        <ResourceBaseClass Value="Form"/>
-      </Unit98>
-      <Unit99>
         <Filename Value="gui\wizards\UWIZModels.pas"/>
         <IsPartOfProject Value="True"/>
-      </Unit99>
+      </Unit88>
     </Units>
   </ProjectOptions>
   <CompilerOptions>
@@ -587,7 +513,7 @@
     </Target>
     <SearchPaths>
       <IncludeFiles Value="$(ProjOutDir);libraries\generics.collections\inc"/>
-      <OtherUnitFiles Value="core;gui;gui\wizards;libraries\synapse;libraries\sphere10;libraries\generics.collections;libraries\pascalcoin;core.utils;gui\wizards\generic wizards"/>
+      <OtherUnitFiles Value="core;gui;gui\wizards;libraries\synapse;libraries\sphere10;libraries\generics.collections;libraries\pascalcoin;core.utils"/>
       <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
     </SearchPaths>
     <Parsing>