Browse Source

first commit of PASC Sending Wizard.

Ugochukwu Mmaduekwe 7 years ago
parent
commit
9f0b8f5ab5

+ 1 - 1
src/gui/UCTRLWallet.lfm

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

+ 193 - 96
src/gui/UCTRLWallet.pas

@@ -9,7 +9,7 @@ interface
 uses
 uses
   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, Menus,
   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, Menus,
   ExtCtrls, PairSplitter, Buttons, UVisualGrid, UCommon.UI,
   ExtCtrls, PairSplitter, Buttons, UVisualGrid, UCommon.UI,
-  UAccounts, UDataSources, UNode;
+  UAccounts, UDataSources, UNode, UWIZSendPASC;
 
 
 type
 type
 
 
@@ -53,14 +53,14 @@ type
     procedure miSendPASCClick(Sender: TObject);
     procedure miSendPASCClick(Sender: TObject);
     procedure miTransferAccountsClick(Sender: TObject);
     procedure miTransferAccountsClick(Sender: TObject);
   private
   private
-    FNodeNotifyEvents : TNodeNotifyEvents;
-    FAccountsMode : TCTRLWalletAccountsMode;
-    FOperationsMode : TCTRLWalletOperationsMode;
-    FOperationsHistory : TCTRLWalletOperationsHistory;
-    FAccountsGrid : TVisualGrid;
-    FOperationsGrid : TVisualGrid;
-    FAccountsDataSource : TUserAccountsDataSource;
-    FOperationsDataSource : TAccountsOperationsDataSource;
+    FNodeNotifyEvents: TNodeNotifyEvents;
+    FAccountsMode: TCTRLWalletAccountsMode;
+    FOperationsMode: TCTRLWalletOperationsMode;
+    FOperationsHistory: TCTRLWalletOperationsHistory;
+    FAccountsGrid: TVisualGrid;
+    FOperationsGrid: TVisualGrid;
+    FAccountsDataSource: TUserAccountsDataSource;
+    FOperationsDataSource: TAccountsOperationsDataSource;
     procedure SetAccountsMode(AMode: TCTRLWalletAccountsMode);
     procedure SetAccountsMode(AMode: TCTRLWalletAccountsMode);
     procedure SetOperationsMode(AMode: TCTRLWalletOperationsMode);
     procedure SetOperationsMode(AMode: TCTRLWalletOperationsMode);
     procedure SetOperationsHistory(AHistory: TCTRLWalletOperationsHistory);
     procedure SetOperationsHistory(AHistory: TCTRLWalletOperationsHistory);
@@ -69,15 +69,23 @@ type
     procedure OnNodeBlocksChanged(Sender: TObject);
     procedure OnNodeBlocksChanged(Sender: TObject);
     procedure OnNodeNewOperation(Sender: TObject);
     procedure OnNodeNewOperation(Sender: TObject);
     procedure OnAccountsUpdated(Sender: TObject);
     procedure OnAccountsUpdated(Sender: TObject);
-    procedure OnAccountsSelected(Sender: TObject; constref ASelection: TVisualGridSelection);
-    procedure OnOperationSelected(Sender: TObject; constref ASelection: TVisualGridSelection);
-    procedure OnAccountsGridColumnInitialize(Sender: TObject; AColIndex:Integer; AColumn: TVisualColumn);
-    procedure OnOperationsGridColumnInitialize(Sender: TObject; AColIndex:Integer; AColumn: TVisualColumn);
-    procedure OnPrepareAccountPopupMenu(Sender: TObject; constref ASelection: TVisualGridSelection; out APopupMenu: TPopupMenu);
+    procedure OnAccountsSelected(Sender: TObject;
+      constref ASelection: TVisualGridSelection);
+    procedure OnOperationSelected(Sender: TObject;
+      constref ASelection: TVisualGridSelection);
+    procedure OnAccountsGridColumnInitialize(Sender: TObject;
+      AColIndex: integer; AColumn: TVisualColumn);
+    procedure OnOperationsGridColumnInitialize(Sender: TObject;
+      AColIndex: integer; AColumn: TVisualColumn);
+    procedure OnPrepareAccountPopupMenu(Sender: TObject;
+      constref ASelection: TVisualGridSelection; out APopupMenu: TPopupMenu);
   public
   public
-    property AccountsMode : TCTRLWalletAccountsMode read FAccountsMode write SetAccountsMode;
-    property OperationsMode : TCTRLWalletOperationsMode read FOperationsMode write SetOperationsMode;
-    property OperationsHistory : TCTRLWalletOperationsHistory read FOperationsHistory write SetOperationsHistory;
+    property AccountsMode: TCTRLWalletAccountsMode
+      read FAccountsMode write SetAccountsMode;
+    property OperationsMode: TCTRLWalletOperationsMode
+      read FOperationsMode write SetOperationsMode;
+    property OperationsHistory: TCTRLWalletOperationsHistory
+      read FOperationsHistory write SetOperationsHistory;
   end;
   end;
 
 
 implementation
 implementation
@@ -91,44 +99,45 @@ uses
 { TCTRLWallet }
 { TCTRLWallet }
 
 
 procedure TCTRLWallet.FormCreate(Sender: TObject);
 procedure TCTRLWallet.FormCreate(Sender: TObject);
-var cmbDuration : TComboBox;
+var
+  cmbDuration: TComboBox;
 begin
 begin
   // event registrations
   // event registrations
-  FNodeNotifyEvents := TNodeNotifyEvents.Create (self);
+  FNodeNotifyEvents := TNodeNotifyEvents.Create(self);
   FNodeNotifyEvents.OnBlocksChanged := OnNodeBlocksChanged;
   FNodeNotifyEvents.OnBlocksChanged := OnNodeBlocksChanged;
   FNodeNotifyEvents.OnOperationsChanged := OnNodeNewOperation;
   FNodeNotifyEvents.OnOperationsChanged := OnNodeNewOperation;
 
 
   // data sources
   // data sources
   FAccountsDataSource := TUserAccountsDataSource.Create(Self);
   FAccountsDataSource := TUserAccountsDataSource.Create(Self);
-  FOperationsDataSource:= TAccountsOperationsDataSource.Create(Self);
+  FOperationsDataSource := TAccountsOperationsDataSource.Create(Self);
 
 
   // grids
   // grids
   FAccountsGrid := TVisualGrid.Create(Self);
   FAccountsGrid := TVisualGrid.Create(Self);
   FAccountsGrid.SortMode := smMultiColumn;
   FAccountsGrid.SortMode := smMultiColumn;
-  FAccountsGrid.FetchDataInThread:= true;
-  FAccountsGrid.AutoPageSize:= true;
-  FAccountsGrid.SelectionType:= stMultiRow;
-  FAccountsGrid.DeselectionType:= dtDefault;
+  FAccountsGrid.FetchDataInThread := True;
+  FAccountsGrid.AutoPageSize := True;
+  FAccountsGrid.SelectionType := stMultiRow;
+  FAccountsGrid.DeselectionType := dtDefault;
   FAccountsGrid.Options := [vgoColAutoFill, vgoColSizing, vgoSortDirectionAllowNone];
   FAccountsGrid.Options := [vgoColAutoFill, vgoColSizing, vgoSortDirectionAllowNone];
-  FAccountsGrid.DefaultColumnWidths := TArray<Integer>.Create(
-    100,                   // Account
+  FAccountsGrid.DefaultColumnWidths :=
+    TArray<integer>.Create(100,                   // Account
     CT_VISUALGRID_STRETCH, // Name
     CT_VISUALGRID_STRETCH, // Name
     100                    // Balance
     100                    // Balance
-  );
-  FAccountsGrid.OnColumnInitialize:= OnAccountsGridColumnInitialize;
+    );
+  FAccountsGrid.OnColumnInitialize := OnAccountsGridColumnInitialize;
   FAccountsGrid.OnSelection := OnAccountsSelected;
   FAccountsGrid.OnSelection := OnAccountsSelected;
   FAccountsGrid.OnFinishedUpdating := OnAccountsUpdated;
   FAccountsGrid.OnFinishedUpdating := OnAccountsUpdated;
-  FAccountsGrid.OnPreparePopupMenu:= OnPrepareAccountPopupMenu;
+  FAccountsGrid.OnPreparePopupMenu := OnPrepareAccountPopupMenu;
 
 
   FOperationsGrid := TVisualGrid.Create(Self);
   FOperationsGrid := TVisualGrid.Create(Self);
   FOperationsGrid.SortMode := smMultiColumn;
   FOperationsGrid.SortMode := smMultiColumn;
-  FOperationsGrid.FetchDataInThread:= true;
-  FOperationsGrid.AutoPageSize:= true;
-  FOperationsGrid.SelectionType:= stRow;
-  FOperationsGrid.DeselectionType:= dtDefault;
+  FOperationsGrid.FetchDataInThread := True;
+  FOperationsGrid.AutoPageSize := True;
+  FOperationsGrid.SelectionType := stRow;
+  FOperationsGrid.DeselectionType := dtDefault;
   FOperationsGrid.Options := [vgoColAutoFill, vgoColSizing, vgoSortDirectionAllowNone];
   FOperationsGrid.Options := [vgoColAutoFill, vgoColSizing, vgoSortDirectionAllowNone];
-  FOperationsGrid.DefaultColumnWidths := TArray<Integer>.Create(
-    130,                   // Time
+  FOperationsGrid.DefaultColumnWidths :=
+    TArray<integer>.Create(130,                   // Time
     CT_VISUALGRID_DEFAULT, // Block
     CT_VISUALGRID_DEFAULT, // Block
     100,                   // Account
     100,                   // Account
     150,                   // Type
     150,                   // Type
@@ -138,13 +147,13 @@ begin
     CT_VISUALGRID_DEFAULT, // Payload
     CT_VISUALGRID_DEFAULT, // Payload
     80,                    // OPHASH
     80,                    // OPHASH
     CT_VISUALGRID_STRETCH  // Description (stretch)
     CT_VISUALGRID_STRETCH  // Description (stretch)
-  );
-  FOperationsGrid.OnColumnInitialize:= OnOperationsGridColumnInitialize;
+    );
+  FOperationsGrid.OnColumnInitialize := OnOperationsGridColumnInitialize;
   FOperationsGrid.OnSelection := OnOperationSelected;
   FOperationsGrid.OnSelection := OnOperationSelected;
   FOperationsGrid.PopupMenu := mnuOperationsPopup;
   FOperationsGrid.PopupMenu := mnuOperationsPopup;
-  FOperationsGrid.Caption.Alignment:= taCenter;
+  FOperationsGrid.Caption.Alignment := taCenter;
   FOperationsGrid.Caption.Text := 'All Account Operations';
   FOperationsGrid.Caption.Text := 'All Account Operations';
-  FOperationsGrid.Caption.Visible := true;
+  FOperationsGrid.Caption.Visible := True;
 
 
   cmbDuration := TComboBox.Create(FOperationsGrid);
   cmbDuration := TComboBox.Create(FOperationsGrid);
   FOperationsGrid.WidgetControl := cmbDuration;
   FOperationsGrid.WidgetControl := cmbDuration;
@@ -154,16 +163,17 @@ begin
     cmbDuration.AddItem('Maximum', TObject(wohFullHistory));
     cmbDuration.AddItem('Maximum', TObject(wohFullHistory));
   finally
   finally
     cmbDuration.Items.EndUpdate;
     cmbDuration.Items.EndUpdate;
-    cmbDuration.ItemIndex:=0;;
+    cmbDuration.ItemIndex := 0;
+    ;
   end;
   end;
-  cmbDuration.OnChange:=cmbDurationChange;
+  cmbDuration.OnChange := cmbDurationChange;
 
 
   // dock operations grid in panel
   // dock operations grid in panel
   paOperations.AddControlDockCenter(FOperationsGrid);
   paOperations.AddControlDockCenter(FOperationsGrid);
 
 
   // Configure grid states
   // Configure grid states
   AccountsMode := wamMyAccounts;
   AccountsMode := wamMyAccounts;
-  OperationsMode:= womAllAccounts;
+  OperationsMode := womAllAccounts;
   OperationsHistory := woh30Days;
   OperationsHistory := woh30Days;
 end;
 end;
 
 
@@ -179,62 +189,73 @@ begin
 
 
 end;
 end;
 
 
-procedure TCTRLWallet.OnAccountsGridColumnInitialize(Sender: TObject; AColIndex:Integer; AColumn: TVisualColumn);
+procedure TCTRLWallet.OnAccountsGridColumnInitialize(Sender: TObject;
+  AColIndex: integer; AColumn: TVisualColumn);
 begin
 begin
   case AColIndex of
   case AColIndex of
-     2: AColumn.InternalColumn.Alignment := taRightJustify;
+    2: AColumn.InternalColumn.Alignment := taRightJustify;
   end;
   end;
 end;
 end;
 
 
-procedure TCTRLWallet.OnOperationsGridColumnInitialize(Sender: TObject; AColIndex:Integer; AColumn: TVisualColumn);
+procedure TCTRLWallet.OnOperationsGridColumnInitialize(Sender: TObject;
+  AColIndex: integer; AColumn: TVisualColumn);
 begin
 begin
   case AColIndex of
   case AColIndex of
-     4, 5, 6: AColumn.InternalColumn.Alignment := taRightJustify;
+    4, 5, 6: AColumn.InternalColumn.Alignment := taRightJustify;
   end;
   end;
 end;
 end;
 
 
 procedure TCTRLWallet.SetAccountsMode(AMode: TCTRLWalletAccountsMode);
 procedure TCTRLWallet.SetAccountsMode(AMode: TCTRLWalletAccountsMode);
 begin
 begin
-  paAccounts.RemoveAllControls(false);
+  paAccounts.RemoveAllControls(False);
   case AMode of
   case AMode of
-     wamMyAccounts: begin
-       FOperationsGrid.DataSource := FOperationsDataSource;
-       FAccountsGrid.DataSource := FAccountsDataSource;
-       FAccountsGrid.Caption.Text := 'My Accounts';
-       paAccounts.AddControlDockCenter(FAccountsGrid);
-       FAccountsGrid.RefreshGrid;
-     end;
-     wamFirstAccount: raise Exception.Create('Not implemented');
+    wamMyAccounts:
+    begin
+      FOperationsGrid.DataSource := FOperationsDataSource;
+      FAccountsGrid.DataSource := FAccountsDataSource;
+      FAccountsGrid.Caption.Text := 'My Accounts';
+      paAccounts.AddControlDockCenter(FAccountsGrid);
+      FAccountsGrid.RefreshGrid;
+    end;
+    wamFirstAccount: raise Exception.Create('Not implemented');
   end;
   end;
 end;
 end;
 
 
 procedure TCTRLWallet.SetOperationsMode(AMode: TCTRLWalletOperationsMode);
 procedure TCTRLWallet.SetOperationsMode(AMode: TCTRLWalletOperationsMode);
 
 
-  function GetAccNo (constref AAccount : TAccount) : Cardinal; overload;
+  function GetAccNo(constref AAccount: TAccount): cardinal; overload;
   begin
   begin
     Result := AAccount.account;
     Result := AAccount.account;
   end;
   end;
 
 
-  function GetAccNo(constref ARow : Variant) : Cardinal; overload;
+  function GetAccNo(constref ARow: variant): cardinal; overload;
   begin
   begin
-    if NOT TAccountComp.AccountTxtNumberToAccountNumber( ARow.Account, Result ) then
-      raise Exception.Create('Internal Error: Unable to parse account number from table row');
+    if not TAccountComp.AccountTxtNumberToAccountNumber(ARow.Account, Result) then
+      raise Exception.Create(
+        'Internal Error: Unable to parse account number from table row');
   end;
   end;
 
 
 begin
 begin
   case AMode of
   case AMode of
-     womAllAccounts: begin
-       FOperationsGrid.Caption.Text := 'All Accounts';
-       FOperationsDataSource.Accounts := TListTool<TAccount, Cardinal>.Transform( FAccountsDataSource.LastKnownUserAccounts, GetAccNo );
-     end;
-     womSelectedAccounts: begin
-       FOperationsGrid.Caption.Text := 'Selected Accounts';
-       FOperationsDataSource.Accounts := TListTool<Variant, Cardinal>.Transform( FAccountsGrid.SelectedRows, GetAccNo);
-     end
-     else raise ENotSupportedException.Create(Format('AMode %d not supported', [Integer(AMode)]));
+    womAllAccounts:
+    begin
+      FOperationsGrid.Caption.Text := 'All Accounts';
+      FOperationsDataSource.Accounts :=
+        TListTool<TAccount, cardinal>.Transform(
+        FAccountsDataSource.LastKnownUserAccounts, GetAccNo);
+    end;
+    womSelectedAccounts:
+    begin
+      FOperationsGrid.Caption.Text := 'Selected Accounts';
+      FOperationsDataSource.Accounts :=
+        TListTool<variant, cardinal>.Transform(FAccountsGrid.SelectedRows, GetAccNo);
+    end
+    else
+      raise ENotSupportedException.Create(Format('AMode %d not supported',
+        [integer(AMode)]));
   end;
   end;
   FOperationsGrid.RefreshGrid;
   FOperationsGrid.RefreshGrid;
-  FOperationsMode:=AMode;
+  FOperationsMode := AMode;
 end;
 end;
 
 
 procedure TCTRLWallet.SetOperationsHistory(AHistory: TCTRLWalletOperationsHistory);
 procedure TCTRLWallet.SetOperationsHistory(AHistory: TCTRLWalletOperationsHistory);
@@ -261,39 +282,48 @@ end;
 
 
 procedure TCTRLWallet.OnAccountsUpdated(Sender: TObject);
 procedure TCTRLWallet.OnAccountsUpdated(Sender: TObject);
 begin
 begin
-   lblTotalPASC.Caption := TAccountComp.FormatMoney( FAccountsDataSource.Overview.TotalPASC );
-   lblTotalPASA.Caption := Format('%d', [FAccountsDataSource.Overview.TotalPASA] );
+  lblTotalPASC.Caption := TAccountComp.FormatMoney(
+    FAccountsDataSource.Overview.TotalPASC);
+  lblTotalPASA.Caption := Format('%d', [FAccountsDataSource.Overview.TotalPASA]);
 end;
 end;
 
 
-procedure TCTRLWallet.OnAccountsSelected(Sender: TObject; constref ASelection: TVisualGridSelection);
+procedure TCTRLWallet.OnAccountsSelected(Sender: TObject;
+  constref ASelection: TVisualGridSelection);
 var
 var
-  row : longint;
-  selectedAccounts : Generics.Collections.TList<Cardinal>;
-  acc : Cardinal;
-  GC : TDisposables;
+  row: longint;
+  selectedAccounts: Generics.Collections.TList<cardinal>;
+  acc: cardinal;
+  GC: TDisposables;
 begin
 begin
-  selectedAccounts := GC.AddObject( TList<Cardinal>.Create ) as TList<Cardinal>;
+  selectedAccounts := GC.AddObject(TList<cardinal>.Create) as TList<cardinal>;
 
 
-  if ASelection.RowCount > 0 then begin
-    for row := ASelection.Row to (ASelection.Row + ASelection.RowCount - 1) do begin
-      if (TAccountComp.AccountTxtNumberToAccountNumber( FAccountsGrid.Rows[row].Account, acc)) then
+  if ASelection.RowCount > 0 then
+  begin
+    for row := ASelection.Row to (ASelection.Row + ASelection.RowCount - 1) do
+    begin
+      if (TAccountComp.AccountTxtNumberToAccountNumber(
+        FAccountsGrid.Rows[row].Account, acc)) then
         selectedAccounts.Add(acc);
         selectedAccounts.Add(acc);
     end;
     end;
     FOperationsDataSource.Accounts := selectedAccounts.ToArray;
     FOperationsDataSource.Accounts := selectedAccounts.ToArray;
     FOperationsGrid.RefreshGrid;
     FOperationsGrid.RefreshGrid;
-  end else begin
-    OperationsMode:= womAllAccounts;
+  end
+  else
+  begin
+    OperationsMode := womAllAccounts;
   end;
   end;
 end;
 end;
 
 
-procedure TCTRLWallet.OnOperationSelected(Sender: TObject; constref ASelection: TVisualGridSelection);
+procedure TCTRLWallet.OnOperationSelected(Sender: TObject;
+  constref ASelection: TVisualGridSelection);
 var
 var
-  row : longint;
-  v : Variant;
-  ophash : AnsiString;
+  row: longint;
+  v: variant;
+  ophash: ansistring;
 begin
 begin
   row := ASelection.Row;
   row := ASelection.Row;
-  if (row >= 0) AND (row < FOperationsGrid.RowCount) then begin
+  if (row >= 0) and (row < FOperationsGrid.RowCount) then
+  begin
     v := FOperationsGrid.Rows[row];
     v := FOperationsGrid.Rows[row];
     ophash := FOperationsGrid.Rows[row].OPHASH;
     ophash := FOperationsGrid.Rows[row].OPHASH;
     if TPCOperation.IsValidOperationHash(ophash) then
     if TPCOperation.IsValidOperationHash(ophash) then
@@ -308,23 +338,25 @@ end;
 
 
 procedure TCTRLWallet.cmbDurationChange(Sender: TObject);
 procedure TCTRLWallet.cmbDurationChange(Sender: TObject);
 var
 var
-  cmbDuration : TComboBox;
+  cmbDuration: TComboBox;
 begin
 begin
   cmbDuration := Sender as TComboBox;
   cmbDuration := Sender as TComboBox;
   if not Assigned(cmbDuration) then
   if not Assigned(cmbDuration) then
     exit;
     exit;
 
 
   case cmbDuration.ItemIndex of
   case cmbDuration.ItemIndex of
-     0: OperationsHistory := woh30Days;
-     1: OperationsHistory := wohFullHistory;
+    0: OperationsHistory := woh30Days;
+    1: OperationsHistory := wohFullHistory;
   end;
   end;
 end;
 end;
 
 
-procedure TCTRLWallet.OnPrepareAccountPopupMenu(Sender: TObject; constref ASelection: TVisualGridSelection; out APopupMenu: TPopupMenu);
+procedure TCTRLWallet.OnPrepareAccountPopupMenu(Sender: TObject;
+  constref ASelection: TVisualGridSelection; out APopupMenu: TPopupMenu);
 begin
 begin
   miSep1.Visible := ASelection.RowCount = 1;
   miSep1.Visible := ASelection.RowCount = 1;
   miAccountInfo.Visible := ASelection.RowCount = 1;
   miAccountInfo.Visible := ASelection.RowCount = 1;
-  miTransferAccounts.Caption := IIF( ASelection.RowCount = 1, 'Transfer Account', 'Transfer Accounts');
+  miTransferAccounts.Caption :=
+    IIF(ASelection.RowCount = 1, 'Transfer Account', 'Transfer Accounts');
   APopupMenu := mnuAccountsPopup;
   APopupMenu := mnuAccountsPopup;
 end;
 end;
 
 
@@ -334,8 +366,72 @@ begin
 end;
 end;
 
 
 procedure TCTRLWallet.miSendPASCClick(Sender: TObject);
 procedure TCTRLWallet.miSendPASCClick(Sender: TObject);
+
+  function GetAccNoWithoutChecksum(constref ARow: variant): cardinal;
+  begin
+    if not TAccountComp.AccountTxtNumberToAccountNumber(ARow.Account, Result) then
+    begin
+      raise Exception.Create(
+        'Internal Error: Unable to parse account number from table row');
+    end;
+  end;
+
+  function GetAccNoWithCheckSum(constref ARow: variant): string;
+  begin
+    Result := ARow.Account;
+  end;
+
+  function GetAccounts(AccountNumbers: TArray<cardinal>): TArray<TAccount>;
+  var
+    acc: TAccount;
+    safeBox: TPCSafeBox;
+    keys: TOrderedAccountKeysList;
+    LContainer: Generics.Collections.TList<TAccount>;
+    i: integer;
+  begin
+    LContainer := Generics.Collections.TList<TAccount>.Create();
+    keys := TWallet.keys.AccountsKeyList;
+    safeBox := TUserInterface.Node.Bank.safeBox;
+    safeBox.StartThreadSafe;
+    try
+      LContainer.Clear;
+      try
+
+        // load selected user accounts
+        for i := 0 to High(AccountNumbers) do
+        begin
+          acc := safeBox.Account(AccountNumbers[i]);
+          if keys.IndexOfAccountKey(acc.accountInfo.accountKey) >= 0 then
+          begin
+            LContainer.Add(acc);
+          end;
+        end;
+      finally
+        safeBox.EndThreadSave;
+      end;
+      Result := LContainer.ToArray;
+    finally
+      LContainer.Free;
+    end;
+
+  end;
+
+var
+  Scoped: TDisposables;
+  wiz: TWIZSendPASCWizard;
+  model: TWizSendPASCModel;
+  AccountNumbersWithoutChecksum: TArray<cardinal>;
 begin
 begin
-  raise ENotImplemented.Create('Not Implemented');
+  wiz := Scoped.AddObject(TWIZSendPASCWizard.Create(nil)) as TWIZSendPASCWizard;
+  model := Scoped.AddObject(TWizSendPASCModel.Create(nil)) as TWizSendPASCModel;
+
+  AccountNumbersWithoutChecksum :=
+    TListTool<variant, cardinal>.Transform(FAccountsGrid.SelectedRows,
+    GetAccNoWithoutChecksum);
+
+  model.SelectedAccounts := GetAccounts(AccountNumbersWithoutChecksum);
+  model.SelectedIndex := 0;
+  wiz.Start(model);
 end;
 end;
 
 
 procedure TCTRLWallet.miTransferAccountsClick(Sender: TObject);
 procedure TCTRLWallet.miTransferAccountsClick(Sender: TObject);
@@ -350,9 +446,10 @@ end;
 
 
 procedure TCTRLWallet.miOperationInfoClick(Sender: TObject);
 procedure TCTRLWallet.miOperationInfoClick(Sender: TObject);
 begin
 begin
-  if FOperationsGrid.Selection.RowCount = 0 then exit;
-  TUserInterface.ShowOperationInfoDialog(Self, FOperationsGrid.SelectedRows[0].EntityKey);
+  if FOperationsGrid.Selection.RowCount = 0 then
+    exit;
+  TUserInterface.ShowOperationInfoDialog(Self,
+    FOperationsGrid.SelectedRows[0].EntityKey);
 end;
 end;
 
 
 end.
 end.
-

+ 76 - 0
src/gui/wizards/UWIZSendPASC.pas

@@ -0,0 +1,76 @@
+unit UWIZSendPASC;
+
+{$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.
+}
+
+interface
+
+uses
+  Classes, SysUtils, Forms, UWizard, UAccounts;
+
+type
+
+  { TWIZSendPASCModel }
+  TWIZSendPASCModel = class(TComponent)
+    public
+      SelectedIndex: Integer;
+      SelectedAccounts: TArray<TAccount>;
+      SignerAccount: TAccount;
+  end;
+
+  { TWIZSendPASCWizard }
+
+  TWIZSendPASCWizard = class(TWizard<TWIZSendPASCModel>)
+    public
+      constructor Create(AOwner: TComponent); override;
+      function DetermineHasNext : boolean; override;
+      function DetermineHasPrevious : boolean;  override;
+      function FinishRequested(out message : AnsiString) : boolean; override;
+      function CancelRequested(out message : AnsiString) : boolean; override;
+  end;
+
+implementation
+
+uses
+  UCrypto,
+  UWallet,
+  UWIZSendPASC_Start,
+  UWIZSendPASC_Transaction,
+  UWIZSendPASC_Confirmation,
+  UWIZSendPASC_Completion;
+
+constructor TWIZSendPASCWizard.Create(AOwner: TComponent);
+begin
+  inherited Create(AOwner, [TWIZSendPASC_Start, TWIZSendPASC_Completion]);
+  TitleText := 'Send PASC';
+  FinishText := 'Send PASC';
+end;
+
+function TWIZSendPASCWizard.DetermineHasNext : boolean;
+begin
+  Result := NOT (CurrentScreen is TWIZSendPASC_Completion);
+end;
+
+function TWIZSendPASCWizard.DetermineHasPrevious : boolean;
+begin
+  Result := inherited DetermineHasPrevious;
+end;
+
+function TWIZSendPASCWizard.FinishRequested(out message : AnsiString) : boolean;
+begin
+  // Execute the PASC Sending here
+    raise ENotImplemented.Create('Operation Not Yet Implemented');
+end;
+
+function TWIZSendPASCWizard.CancelRequested(out message : AnsiString) : boolean;
+begin
+  Result := true;
+end;
+
+end.
+

+ 18 - 0
src/gui/wizards/UWIZSendPASC_Completion.lfm

@@ -0,0 +1,18 @@
+object WIZSendPASC_Completion: TWIZSendPASC_Completion
+  Left = 0
+  Height = 253
+  Top = 0
+  Width = 429
+  Caption = 'WIZSendPASC_Completion'
+  ClientHeight = 253
+  ClientWidth = 429
+  Visible = False
+  object Button1: TButton
+    Left = 203
+    Height = 25
+    Top = 153
+    Width = 75
+    Caption = 'Button1'
+    TabOrder = 0
+  end
+end

+ 49 - 0
src/gui/wizards/UWIZSendPASC_Completion.pas

@@ -0,0 +1,49 @@
+unit UWIZSendPASC_Completion;
+
+{$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,
+  UWizard, UWIZSendPASC;
+
+type
+
+  { TWIZSendPASC_Completion }
+
+  TWIZSendPASC_Completion = class(TWizardForm<TWIZSendPASCModel>)
+    Button1: TButton;
+
+
+  public
+    procedure OnPresent; override;
+    procedure OnNext; override;
+  end;
+
+
+implementation
+
+{$R *.lfm}
+
+{ TWIZSendPASC_Completion }
+
+procedure TWIZSendPASC_Completion.OnPresent;
+begin
+  inherited OnPresent;
+end;
+
+procedure TWIZSendPASC_Completion.OnNext;
+begin
+  inherited OnNext;
+end;
+
+end.
+

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

@@ -0,0 +1,18 @@
+object WIZSendPASC_Confirmation: TWIZSendPASC_Confirmation
+  Left = 0
+  Height = 253
+  Top = 0
+  Width = 429
+  Caption = 'WIZSendPASC_Confirmation'
+  ClientHeight = 253
+  ClientWidth = 429
+  Visible = False
+  object Edit1: TEdit
+    Left = 144
+    Height = 23
+    Top = 148
+    Width = 80
+    TabOrder = 0
+    Text = 'Edit1'
+  end
+end

+ 48 - 0
src/gui/wizards/UWIZSendPASC_Confirmation.pas

@@ -0,0 +1,48 @@
+unit UWIZSendPASC_Confirmation;
+
+{$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,
+  UWizard, UWIZSendPASC;
+
+type
+
+  { TWIZSendPASC_Confirmation }
+
+  TWIZSendPASC_Confirmation = class(TWizardForm<TWIZSendPASCModel>)
+    Edit1: TEdit;
+
+  public
+    procedure OnPresent; override;
+    procedure OnNext; override;
+  end;
+
+
+implementation
+
+{$R *.lfm}
+
+{ TWIZSendPASC_Confirmation }
+
+procedure TWIZSendPASC_Confirmation.OnPresent;
+begin
+  inherited OnPresent;
+end;
+
+procedure TWIZSendPASC_Confirmation.OnNext;
+begin
+  inherited OnNext;
+end;
+
+end.
+

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

@@ -0,0 +1,33 @@
+object WIZSendPASC_Start: TWIZSendPASC_Start
+  Left = 0
+  Height = 253
+  Top = 0
+  Width = 429
+  ActiveControl = txtSelectedAccountNumbersAndBalances
+  Caption = 'WIZSendPASC_Start'
+  ClientHeight = 253
+  ClientWidth = 429
+  LCLVersion = '1.8.1.0'
+  Visible = False
+  object Label1: TLabel
+    Left = 96
+    Height = 32
+    Top = 16
+    Width = 479
+    Anchors = [akTop, akLeft, akRight]
+    AutoSize = False
+    Caption = 'List of Selected Accounts and Balances'
+    ParentColor = False
+    WordWrap = True
+  end
+  object txtSelectedAccountNumbersAndBalances: TMemo
+    Left = 24
+    Height = 160
+    Top = 56
+    Width = 379
+    Anchors = [akTop, akLeft, akRight, akBottom]
+    ReadOnly = True
+    ScrollBars = ssBoth
+    TabOrder = 0
+  end
+end

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

@@ -0,0 +1,63 @@
+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.
+}
+
+interface
+
+uses
+  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
+  UWizard, UWIZSendPASC, UWIZSendPASC_Transaction, UWIZSendPASC_Completion;
+
+type
+
+  { TWIZSendPASC_Start }
+
+  TWIZSendPASC_Start = class(TWizardForm<TWIZSendPASCModel>)
+    Label1: TLabel;
+    txtSelectedAccountNumbersAndBalances: TMemo;
+  public
+    procedure OnPresent; override;
+    procedure OnNext; override;
+  end;
+
+
+implementation
+
+{$R *.lfm}
+
+uses UAccounts;
+
+{ TWIZSendPASC_Start }
+
+
+procedure TWIZSendPASC_Start.OnPresent;
+
+function GetAccNoWithChecksum(const AAccountNumber: Cardinal): String;
+begin
+  result := TAccountComp.AccountNumberToAccountTxtNumber(AAccountNumber);
+end;
+var
+  acc: TAccount;
+  i: Integer;
+begin
+  txtSelectedAccountNumbersAndBalances.Clear;
+  for i := 0 to High(Model.SelectedAccounts) do
+  begin
+    acc := Model.SelectedAccounts[i];
+    txtSelectedAccountNumbersAndBalances.Append(Format('This Account %s has %s PASC', [GetAccNoWithChecksum(acc.Account), TAccountComp.FormatMoney(acc.balance)]));
+  end;
+end;
+
+procedure TWIZSendPASC_Start.OnNext;
+begin
+  UpdatePath(ptReplaceAllNext, [TWIZSendPASC_Transaction, TWIZSendPASC_Completion]);
+end;
+
+end.
+

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

@@ -0,0 +1,150 @@
+object WIZSendPASC_Transaction: TWIZSendPASC_Transaction
+  Left = 0
+  Height = 253
+  Top = 0
+  Width = 429
+  ActiveControl = cbSignerAccount
+  Caption = 'WIZSendPASC_Transaction'
+  ClientHeight = 253
+  ClientWidth = 429
+  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

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

@@ -0,0 +1,225 @@
+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_Completion;
+
+type
+
+  { TWIZSendPASC_Transaction }
+
+  TWIZSendPASC_Transaction = class(TWizardForm<TWIZSendPASCModel>)
+    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;
+
+{ 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.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.SelectedAccounts) do
+    begin
+      acc := Model.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.SelectedIndex;
+  cbSignerAccountChange(Self);
+  lblTotalBalanceValue.Caption :=
+    Format('%s PASC', [TAccountComp.FormatMoney(totalBalance)]);
+
+  if Length(Model.SelectedAccounts) > 1 then
+  begin
+    edtAmt.Text := 'ALL BALANCE';
+    edtAmt.Enabled := False;
+  end
+  else
+  begin
+    edtAmt.Text := TAccountComp.FormatMoney(0);
+  end;
+  edtOpFee.Text := TAccountComp.FormatMoney(0);
+end;
+
+procedure TWIZSendPASC_Transaction.OnNext;
+begin
+  Model.SelectedIndex := cbSignerAccount.ItemIndex;
+  Model.SignerAccount := Model.SelectedAccounts[PtrInt(cbSignerAccount.Items.Objects[cbSignerAccount.ItemIndex])];
+  UpdatePath(ptReplaceAllNext, [TWIZSendPASC_Confirmation, TWIZSendPASC_Completion]);
+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;
+begin
+  Accounts := Model.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), opfee) then
+  begin
+    message := 'Invalid fee value "' + edtOpFee.Text + '"';
+    Result := False;
+    Exit;
+  end;
+
+  if Length(Model.SelectedAccounts) = 1 then
+  begin
+    if (Accounts[0].balance < (amount + opfee)) then
+    begin
+      message := 'Insufficient funds';
+      Result := False;
+      Exit;
+    end;
+  end;
+
+end;
+
+end.

+ 30 - 2
src/pascalcoin_wallet.lpi

@@ -33,7 +33,7 @@
         <PackageName Value="LCL"/>
         <PackageName Value="LCL"/>
       </Item1>
       </Item1>
     </RequiredPackages>
     </RequiredPackages>
-    <Units Count="70">
+    <Units Count="74">
       <Unit0>
       <Unit0>
         <Filename Value="pascalcoin_wallet.dpr"/>
         <Filename Value="pascalcoin_wallet.dpr"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
@@ -388,9 +388,37 @@
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
       </Unit68>
       </Unit68>
       <Unit69>
       <Unit69>
-        <Filename Value="libraries\sphere10\UAutoScope.pas"/>
+        <Filename Value="gui\wizards\UWIZSendPASC.pas"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
       </Unit69>
       </Unit69>
+      <Unit70>
+        <Filename Value="gui\wizards\UWIZSendPASC_Confirmation.pas"/>
+        <IsPartOfProject Value="True"/>
+        <ComponentName Value="WIZSendPASC_Confirmation"/>
+        <HasResources Value="True"/>
+        <ResourceBaseClass Value="Form"/>
+      </Unit70>
+      <Unit71>
+        <Filename Value="gui\wizards\UWIZSendPASC_Start.pas"/>
+        <IsPartOfProject Value="True"/>
+        <ComponentName Value="WIZSendPASC_Start"/>
+        <HasResources Value="True"/>
+        <ResourceBaseClass Value="Form"/>
+      </Unit71>
+      <Unit72>
+        <Filename Value="gui\wizards\UWIZSendPASC_Transaction.pas"/>
+        <IsPartOfProject Value="True"/>
+        <ComponentName Value="WIZSendPASC_Transaction"/>
+        <HasResources Value="True"/>
+        <ResourceBaseClass Value="Form"/>
+      </Unit72>
+      <Unit73>
+        <Filename Value="gui\wizards\UWIZSendPASC_Completion.pas"/>
+        <IsPartOfProject Value="True"/>
+        <ComponentName Value="WIZSendPASC_Completion"/>
+        <HasResources Value="True"/>
+        <ResourceBaseClass Value="Form"/>
+      </Unit73>
     </Units>
     </Units>
   </ProjectOptions>
   </ProjectOptions>
   <CompilerOptions>
   <CompilerOptions>