Browse Source

Add: first implementation of EnlistAccounts Wizard (Subject to Review).

deleted some unneeded files.
Ugochukwu Mmaduekwe 7 years ago
parent
commit
ea3d187e5f
32 changed files with 971 additions and 1051 deletions
  1. 18 2
      src/gui/UCTRLWallet.pas
  2. 19 2
      src/gui/wizards/UWIZModels.pas
  3. 1 0
      src/gui/wizards/operations/UWIZChangeKey_Confirmation.lfm
  4. 3 29
      src/gui/wizards/operations/UWIZChangeKey_Confirmation.pas
  5. 59 114
      src/gui/wizards/operations/UWIZEnlistAccountForSale.pas
  6. 4 4
      src/gui/wizards/operations/UWIZEnlistAccountForSale_ConfirmAccount.lfm
  7. 128 0
      src/gui/wizards/operations/UWIZEnlistAccountForSale_ConfirmAccount.pas
  8. 1 0
      src/gui/wizards/operations/UWIZEnlistAccountForSale_Confirmation.lfm
  9. 38 33
      src/gui/wizards/operations/UWIZEnlistAccountForSale_Confirmation.pas
  10. 36 0
      src/gui/wizards/operations/UWIZEnlistAccountForSale_EnterLockingBlock.lfm
  11. 63 0
      src/gui/wizards/operations/UWIZEnlistAccountForSale_EnterLockingBlock.pas
  12. 36 0
      src/gui/wizards/operations/UWIZEnlistAccountForSale_EnterPublicKey.lfm
  13. 79 0
      src/gui/wizards/operations/UWIZEnlistAccountForSale_EnterPublicKey.pas
  14. 52 0
      src/gui/wizards/operations/UWIZEnlistAccountForSale_EnterSaleAmount.lfm
  15. 118 0
      src/gui/wizards/operations/UWIZEnlistAccountForSale_EnterSaleAmount.pas
  16. 53 87
      src/gui/wizards/operations/UWIZEnlistAccountForSale_EnterSeller.lfm
  17. 159 0
      src/gui/wizards/operations/UWIZEnlistAccountForSale_EnterSeller.pas
  18. 0 141
      src/gui/wizards/operations/UWIZEnlistAccountForSale_List.pas
  19. 0 50
      src/gui/wizards/operations/UWIZEnlistAccountForSale_PrivateSaleConfig.lfm
  20. 0 92
      src/gui/wizards/operations/UWIZEnlistAccountForSale_PrivateSaleConfig.pas
  21. 3 3
      src/gui/wizards/operations/UWIZEnlistAccountForSale_SelectOption.lfm
  22. 11 14
      src/gui/wizards/operations/UWIZEnlistAccountForSale_SelectOption.pas
  23. 0 199
      src/gui/wizards/operations/UWIZEnlistAccountForSale_Transaction.pas
  24. 0 98
      src/gui/wizards/operations/UWIZEnlistAccountForSale_TransactionPayload.lfm
  25. 0 82
      src/gui/wizards/operations/UWIZEnlistAccountForSale_TransactionPayload.pas
  26. 1 0
      src/gui/wizards/operations/UWIZOperationFee_Custom.lfm
  27. 26 6
      src/gui/wizards/operations/UWIZOperationFee_Custom.pas
  28. 0 36
      src/gui/wizards/operations/UWIZOperationPayload_Encryption.lrs
  29. 1 0
      src/gui/wizards/operations/UWIZSendPASC.pas
  30. 1 0
      src/gui/wizards/operations/UWIZSendPASC_Confirmation.lfm
  31. 0 15
      src/gui/wizards/operations/UWIZSendPASC_Confirmation.pas
  32. 61 44
      src/pascalcoin_wallet.lpi

+ 18 - 2
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, Generics.Collections,
   ExtCtrls, PairSplitter, Buttons, UVisualGrid, UCommon.UI, Generics.Collections,
-  UAccounts, UDataSources, UNode, UWIZSendPASC, UWIZChangeKey, UCoreObjects, UCoreUtils;
+  UAccounts, UDataSources, UNode, UCoreObjects, UCoreUtils, UWIZSendPASC, UWIZChangeKey, UWIZEnlistAccountForSale;
 
 
 type
 type
 
 
@@ -670,8 +670,24 @@ begin
 end;
 end;
 
 
 procedure TCTRLWallet.miEnlistAccountsForSaleClick(Sender: TObject);
 procedure TCTRLWallet.miEnlistAccountsForSaleClick(Sender: TObject);
+var
+  Scoped: TDisposables;
+  wiz: TWIZEnlistAccountForSaleWizard;
+  model: TWIZOperationsModel;
+  AccountNumbersWithoutChecksum: TArray<cardinal>;
+
+   function GetAccNoWithoutChecksum(constref ARow: variant): cardinal;
+  begin
+    Result := ARow.__KEY;
+  end;
+
+
 begin
 begin
- raise ENotImplemented.Create('not yet implemented.');
+  wiz := Scoped.AddObject(TWIZEnlistAccountForSaleWizard.Create(nil)) as TWIZEnlistAccountForSaleWizard;
+  model := TWIZOperationsModel.Create(wiz, omtEnlistAccountForSale);
+  AccountNumbersWithoutChecksum := TListTool<variant, cardinal>.Transform(FAccountsGrid.SelectedRows, GetAccNoWithoutChecksum);
+  model.Account.SelectedAccounts := GetAccounts(AccountNumbersWithoutChecksum);
+  wiz.Start(model);
 end;
 end;
 
 
 procedure TCTRLWallet.miDelistAccountsFromSaleClick(Sender: TObject);
 procedure TCTRLWallet.miDelistAccountsFromSaleClick(Sender: TObject);

+ 19 - 2
src/gui/wizards/UWIZModels.pas

@@ -35,7 +35,7 @@ type
 
 
     { TModelType }
     { TModelType }
 
 
-    TModelType = (omtAccount, omtSendPasc, omtChangeKey, omtTransferAccount, omtChangeAccountPrivateKey, omtAddKey);
+    TModelType = (omtAccount, omtSendPasc, omtChangeKey, omtTransferAccount, omtChangeAccountPrivateKey, omtAddKey, omtEnlistAccountForSale);
 
 
     { TPayloadEncryptionMode }
     { TPayloadEncryptionMode }
 
 
@@ -49,10 +49,14 @@ type
 
 
     TChangeKeyMode = (akaTransferAccountOwnership, akaChangeAccountPrivateKey);
     TChangeKeyMode = (akaTransferAccountOwnership, akaChangeAccountPrivateKey);
 
 
-     { TSendPASCMode }
+    { TSendPASCMode }
 
 
     TSendPASCMode = (akaAllBalance, akaSpecifiedAmount);
     TSendPASCMode = (akaAllBalance, akaSpecifiedAmount);
 
 
+    { TAccountSaleMode }
+    TAccountSaleMode = (akaPublicSale, akaPrivateSale);
+
+
     { TAccountModel }
     { TAccountModel }
 
 
     TAccountModel = class(TComponent)
     TAccountModel = class(TComponent)
@@ -91,6 +95,16 @@ type
       NewWalletKey: TWalletKey;
       NewWalletKey: TWalletKey;
     end;
     end;
 
 
+    { TWIZEnlistAccountForSaleModel }
+    TEnlistAccountForSaleModel = class(TComponent)
+    public
+      SalePrice: int64;
+      NewOwnerPublicKey: TAccountKey;
+      LockedUntilBlock: cardinal;
+      SellerAccount: TAccount;
+      AccountSaleMode: TAccountSaleMode;
+    end;
+
     { TFeeModel }
     { TFeeModel }
 
 
     TFeeModel = class(TComponent)
     TFeeModel = class(TComponent)
@@ -125,6 +139,7 @@ type
     FChangeKey: TChangeKeyModel;
     FChangeKey: TChangeKeyModel;
     FTransferAccount: TTransferAccountModel;
     FTransferAccount: TTransferAccountModel;
     FChangeAccountPrivateKey: TChangeAccountPrivateKeyModel;
     FChangeAccountPrivateKey: TChangeAccountPrivateKeyModel;
+    FEnlistAccountForSale: TEnlistAccountForSaleModel;
     FFee: TFeeModel;
     FFee: TFeeModel;
     FSigner: TSignerModel;
     FSigner: TSignerModel;
     FPayload: TPayloadModel;
     FPayload: TPayloadModel;
@@ -136,6 +151,7 @@ type
     property ChangeKey: TChangeKeyModel read FChangeKey;
     property ChangeKey: TChangeKeyModel read FChangeKey;
     property TransferAccount: TTransferAccountModel read FTransferAccount;
     property TransferAccount: TTransferAccountModel read FTransferAccount;
     property ChangeAccountPrivateKey: TChangeAccountPrivateKeyModel read FChangeAccountPrivateKey;
     property ChangeAccountPrivateKey: TChangeAccountPrivateKeyModel read FChangeAccountPrivateKey;
+    property EnlistAccountForSale: TEnlistAccountForSaleModel read FEnlistAccountForSale;
     property Fee: TFeeModel read FFee;
     property Fee: TFeeModel read FFee;
     property Signer: TSignerModel read FSigner;
     property Signer: TSignerModel read FSigner;
     property Payload: TPayloadModel read FPayload;
     property Payload: TPayloadModel read FPayload;
@@ -152,6 +168,7 @@ begin
   FChangeKey := TChangeKeyModel.Create(Self);
   FChangeKey := TChangeKeyModel.Create(Self);
   FTransferAccount := TTransferAccountModel.Create(Self);
   FTransferAccount := TTransferAccountModel.Create(Self);
   FChangeAccountPrivateKey := TChangeAccountPrivateKeyModel.Create(Self);
   FChangeAccountPrivateKey := TChangeAccountPrivateKeyModel.Create(Self);
+  FEnlistAccountForSale := TEnlistAccountForSaleModel.Create(Self);
   FFee := TFeeModel.Create(Self);
   FFee := TFeeModel.Create(Self);
   FSigner := TSignerModel.Create(Self);
   FSigner := TSignerModel.Create(Self);
   FPayload := TPayloadModel.Create(Self);
   FPayload := TPayloadModel.Create(Self);

+ 1 - 0
src/gui/wizards/operations/UWIZChangeKey_Confirmation.lfm

@@ -6,6 +6,7 @@ object WIZChangeKey_Confirmation: TWIZChangeKey_Confirmation
   Caption = 'WIZChangeKey_Confirmation'
   Caption = 'WIZChangeKey_Confirmation'
   ClientHeight = 320
   ClientHeight = 320
   ClientWidth = 511
   ClientWidth = 511
+  LCLVersion = '1.8.2.0'
   Visible = False
   Visible = False
   object GroupBox1: TGroupBox
   object GroupBox1: TGroupBox
     Left = 10
     Left = 10

+ 3 - 29
src/gui/wizards/operations/UWIZChangeKey_Confirmation.pas

@@ -35,7 +35,6 @@ type
   public
   public
     procedure OnPresent; override;
     procedure OnPresent; override;
     procedure OnNext; override;
     procedure OnNext; override;
-    function Validate(out message: ansistring): boolean; override;
   end;
   end;
 
 
 
 
@@ -113,27 +112,11 @@ end;
 
 
 procedure TWIZChangeKey_Confirmation.OnNext;
 procedure TWIZChangeKey_Confirmation.OnNext;
 var
 var
-  locked: Boolean;
+  locked: boolean;
 begin
 begin
-  locked := (NOT TWallet.Keys.HasPassword) OR (NOT TWallet.Keys.IsValidPassword);
+  locked := (not TWallet.Keys.HasPassword) or (not TWallet.Keys.IsValidPassword);
   if locked then
   if locked then
-  begin
     TUserInterface.UnlockWallet(Self);
     TUserInterface.UnlockWallet(Self);
-  end;
-end;
-
-function TWIZChangeKey_Confirmation.Validate(out message: ansistring): boolean;
-begin
-  Result := True;
-  if Length(Model.Account.SelectedAccounts) > 1 then
-  begin
-    if not (Model.Fee.SingleOperationFee > 0) then
-    begin
-      message := 'insufficient fee for total operation.';
-      Result := False;
-      Exit;
-    end;
-  end;
 end;
 end;
 
 
 { TAccountChangeKeyDataSource }
 { TAccountChangeKeyDataSource }
@@ -157,20 +140,16 @@ begin
   else if ABindingName = 'Fee' then
   else if ABindingName = 'Fee' then
     Result := TAccountComp.FormatMoney(Model.Fee.SingleOperationFee)
     Result := TAccountComp.FormatMoney(Model.Fee.SingleOperationFee)
   else
   else
-  begin
     case Model.ChangeKey.ChangeKeyMode of
     case Model.ChangeKey.ChangeKeyMode of
       akaTransferAccountOwnership:
       akaTransferAccountOwnership:
-      begin
         if ABindingName = 'CurrentKey' then
         if ABindingName = 'CurrentKey' then
           Result := TAccountComp.AccountPublicKeyExport(AItem.accountInfo.accountKey)
           Result := TAccountComp.AccountPublicKeyExport(AItem.accountInfo.accountKey)
         else if ABindingName = 'NewKey' then
         else if ABindingName = 'NewKey' then
           Result := TAccountComp.AccountPublicKeyExport(Model.TransferAccount.AccountKey)
           Result := TAccountComp.AccountPublicKeyExport(Model.TransferAccount.AccountKey)
         else
         else
           raise Exception.Create(Format('Field not found [%s]', [ABindingName]));
           raise Exception.Create(Format('Field not found [%s]', [ABindingName]));
-      end;
 
 
       akaChangeAccountPrivateKey:
       akaChangeAccountPrivateKey:
-      begin
         if ABindingName = 'CurrentKey' then
         if ABindingName = 'CurrentKey' then
           { TODO : Check how to get the wallet name an account is in }
           { TODO : Check how to get the wallet name an account is in }
           Result := '??? unknown'
           Result := '??? unknown'
@@ -180,16 +159,12 @@ begin
             TCrypto.ToHexaString(TAccountComp.AccountKey2RawString(
             TCrypto.ToHexaString(TAccountComp.AccountKey2RawString(
             Model.ChangeAccountPrivateKey.NewWalletKey.AccountKey)), Model.ChangeAccountPrivateKey.NewWalletKey.Name);
             Model.ChangeAccountPrivateKey.NewWalletKey.AccountKey)), Model.ChangeAccountPrivateKey.NewWalletKey.Name);
           if not Assigned(Model.ChangeAccountPrivateKey.NewWalletKey.PrivateKey) then
           if not Assigned(Model.ChangeAccountPrivateKey.NewWalletKey.PrivateKey) then
-          begin
             Result := Result + '(*)';
             Result := Result + '(*)';
-          end;
         end
         end
         else
         else
           raise Exception.Create(Format('Field not found [%s]', [ABindingName]));
           raise Exception.Create(Format('Field not found [%s]', [ABindingName]));
-      end;
 
 
     end;
     end;
-  end;
 
 
 end;
 end;
 
 
@@ -199,9 +174,8 @@ var
   i: integer;
   i: integer;
 begin
 begin
   for i := Low(Model.Account.SelectedAccounts) to High(Model.Account.SelectedAccounts) do
   for i := Low(Model.Account.SelectedAccounts) to High(Model.Account.SelectedAccounts) do
-  begin
     AContainer.Add(Model.Account.SelectedAccounts[i]);
     AContainer.Add(Model.Account.SelectedAccounts[i]);
-  end;
+
 end;
 end;
 
 
 
 

+ 59 - 114
src/gui/wizards/operations/UWIZEnlistAccountForSale.pas

@@ -12,41 +12,17 @@ unit UWIZEnlistAccountForSale;
 interface
 interface
 
 
 uses
 uses
-  Classes, SysUtils, Forms, Dialogs, UCrypto, UCommon, UWizard, UAccounts, LCLType;
+  Classes, SysUtils, Forms, Dialogs, UCrypto, UCommon, UWizard, UAccounts, UWIZModels, LCLType;
 
 
 type
 type
 
 
-  { TWIZEnlistAccountForSaleModel }
-  TWIZAccountSaleMode = (akaPublicSale, akaPrivateSale);
-  TWIZPayloadEncryptionMode = (akaEncryptWithOldEC, akaEncryptWithEC,
-    akaEncryptWithPassword, akaNotEncrypt);
-
-  TWIZEnlistAccountForSaleModel = class(TComponent)
-  public
-    DefaultFee: int64;
-    NewPublicKey, Payload, EncryptionPassword: string;
-    SelectedIndex: integer;
-    SalePrice: int64;
-    NewOwnerPublicKey: TAccountKey;
-    LockedUntilBlock: cardinal;
-    EncodedPayload: TRawBytes;
-    SignerAccount, SellerAccount: TAccount;
-    SelectedAccounts: TArray<TAccount>;
-    PayloadEncryptionMode: TWIZPayloadEncryptionMode;
-    AccountSaleMode: TWIZAccountSaleMode;
-  end;
-
   { TWIZEnlistAccountForSaleWizard }
   { TWIZEnlistAccountForSaleWizard }
 
 
-  TWIZEnlistAccountForSaleWizard = class(TWizard<TWIZEnlistAccountForSaleModel>)
+  TWIZEnlistAccountForSaleWizard = class(TWizard<TWIZOperationsModel>)
   private
   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 UpdateOperationOptions(var errors: string): boolean;
-    function UpdateOpListForSale(const TargetAccount: TAccount;
-      var SalePrice: int64; var SellerAccount, SignerAccount: TAccount;
-      var NewOwnerPublicKey: TAccountKey; var LockedUntilBlock: cardinal;
-      var errors: ansistring): boolean;
+    function UpdateOpListForSale(const TargetAccount: TAccount; var SalePrice: int64; var SellerAccount, SignerAccount: TAccount; var NewOwnerPublicKey: TAccountKey; var LockedUntilBlock: cardinal; var errors: ansistring): boolean;
     procedure EnlistAccountForSale();
     procedure EnlistAccountForSale();
   public
   public
     constructor Create(AOwner: TComponent); override;
     constructor Create(AOwner: TComponent); override;
@@ -66,13 +42,15 @@ uses
   UWallet,
   UWallet,
   UECIES,
   UECIES,
   UAES,
   UAES,
-  UWIZEnlistAccountForSale_Start,
+  UWIZEnlistAccountForSale_ConfirmAccount,
+  UWIZEnlistAccountForSale_SelectOption,
+  UWIZEnlistAccountForSale_EnterSeller,
+  UWIZEnlistAccountForSale_EnterSaleAmount,
   UWIZEnlistAccountForSale_Confirmation;
   UWIZEnlistAccountForSale_Confirmation;
 
 
 { TWIZEnlistAccountForSaleWizard }
 { TWIZEnlistAccountForSaleWizard }
 
 
-function TWIZEnlistAccountForSaleWizard.UpdatePayload(const SenderAccount: TAccount;
-  var errors: string): boolean;
+function TWIZEnlistAccountForSaleWizard.UpdatePayload(const SenderAccount: TAccount; var errors: string): boolean;
 var
 var
   valid: boolean;
   valid: boolean;
   payload_encrypted, payload_u: string;
   payload_encrypted, payload_u: string;
@@ -80,9 +58,9 @@ var
 begin
 begin
   valid := False;
   valid := False;
   payload_encrypted := '';
   payload_encrypted := '';
-  Model.EncodedPayload := '';
+  Model.Payload.EncodedBytes := '';
   errors := 'Unknown error';
   errors := 'Unknown error';
-  payload_u := Model.Payload;
+  payload_u := Model.Payload.Content;
 
 
   try
   try
     if (payload_u = '') then
     if (payload_u = '') then
@@ -90,9 +68,9 @@ begin
       valid := True;
       valid := True;
       Exit;
       Exit;
     end;
     end;
-    case Model.PayloadEncryptionMode of
+    case Model.Payload.Mode of
 
 
-      akaEncryptWithOldEC:
+      akaEncryptWithSender:
       begin
       begin
         // Use sender
         // Use sender
         errors := 'Error encrypting';
         errors := 'Error encrypting';
@@ -101,11 +79,11 @@ begin
         valid := payload_encrypted <> '';
         valid := payload_encrypted <> '';
       end;
       end;
 
 
-      akaEncryptWithEC:
+      akaEncryptWithReceiver:
       begin
       begin
         errors := 'Public key: ' + 'Error encrypting';
         errors := 'Public key: ' + 'Error encrypting';
 
 
-        account := Model.SignerAccount;
+        account := Model.Signer.SignerAccount;
         payload_encrypted := ECIESEncrypt(account.accountInfo.accountKey, payload_u);
         payload_encrypted := ECIESEncrypt(account.accountInfo.accountKey, payload_u);
         valid := payload_encrypted <> '';
         valid := payload_encrypted <> '';
       end;
       end;
@@ -113,7 +91,7 @@ begin
       akaEncryptWithPassword:
       akaEncryptWithPassword:
       begin
       begin
         payload_encrypted := TAESComp.EVP_Encrypt_AES256(
         payload_encrypted := TAESComp.EVP_Encrypt_AES256(
-          payload_u, Model.EncryptionPassword);
+          payload_u, Model.Payload.Password);
         valid := payload_encrypted <> '';
         valid := payload_encrypted <> '';
       end;
       end;
 
 
@@ -124,30 +102,24 @@ begin
       end
       end
 
 
       else
       else
-      begin
         raise Exception.Create('Invalid Encryption Selection');
         raise Exception.Create('Invalid Encryption Selection');
-      end;
     end;
     end;
 
 
   finally
   finally
     if valid then
     if valid then
-    begin
       if length(payload_encrypted) > CT_MaxPayloadSize then
       if length(payload_encrypted) > CT_MaxPayloadSize then
       begin
       begin
         valid := False;
         valid := False;
         errors := 'Payload size is bigger than ' + IntToStr(CT_MaxPayloadSize) +
         errors := 'Payload size is bigger than ' + IntToStr(CT_MaxPayloadSize) +
           ' (' + IntToStr(length(payload_encrypted)) + ')';
           ' (' + IntToStr(length(payload_encrypted)) + ')';
       end;
       end;
-
-    end;
-    Model.EncodedPayload := payload_encrypted;
+    Model.Payload.EncodedBytes := payload_encrypted;
     Result := valid;
     Result := valid;
   end;
   end;
 
 
 end;
 end;
 
 
-function TWIZEnlistAccountForSaleWizard.UpdateOperationOptions(
-  var errors: string): boolean;
+function TWIZEnlistAccountForSaleWizard.UpdateOperationOptions(var errors: string): boolean;
 var
 var
   iAcc, iWallet: integer;
   iAcc, iWallet: integer;
   sender_account, signer_account, seller_account: TAccount;
   sender_account, signer_account, seller_account: TAccount;
@@ -165,17 +137,15 @@ begin
     Exit;
     Exit;
   end;
   end;
 
 
-  if Length(Model.SelectedAccounts) = 0 then
+  if Length(Model.Account.SelectedAccounts) = 0 then
   begin
   begin
     errors := 'No sender account';
     errors := 'No sender account';
     Exit;
     Exit;
   end
   end
   else
   else
-  begin
-
-    for iAcc := Low(Model.SelectedAccounts) to High(Model.SelectedAccounts) do
+    for iAcc := Low(Model.Account.SelectedAccounts) to High(Model.Account.SelectedAccounts) do
     begin
     begin
-      sender_account := Model.SelectedAccounts[iAcc];
+      sender_account := Model.Account.SelectedAccounts[iAcc];
       iWallet := TWallet.Keys.IndexOfAccountKey(sender_account.accountInfo.accountKey);
       iWallet := TWallet.Keys.IndexOfAccountKey(sender_account.accountInfo.accountKey);
       if (iWallet < 0) then
       if (iWallet < 0) then
       begin
       begin
@@ -188,30 +158,22 @@ begin
       if not assigned(wk.PrivateKey) then
       if not assigned(wk.PrivateKey) then
       begin
       begin
         if wk.CryptedKey <> '' then
         if wk.CryptedKey <> '' then
-        begin
-          // TODO: handle unlocking of encrypted wallet here
-          errors := 'Wallet is password protected. Need password';
-        end
+          errors := 'Wallet is password protected. Need password'// TODO: handle unlocking of encrypted wallet here
+
         else
         else
-        begin
           errors := 'Only public key of account ' +
           errors := 'Only public key of account ' +
             TAccountComp.AccountNumberToAccountTxtNumber(sender_account.account) +
             TAccountComp.AccountNumberToAccountTxtNumber(sender_account.account) +
             ' found in wallet. You cannot operate with this account';
             ' found in wallet. You cannot operate with this account';
-        end;
         Exit;
         Exit;
       end;
       end;
     end;
     end;
-  end;
 
 
-  Result := UpdateOpListForSale(Model.SelectedAccounts[0], salePrice,
+  Result := UpdateOpListForSale(Model.Account.SelectedAccounts[0], salePrice,
     seller_account, signer_account, publicKey, auxC, errors);
     seller_account, signer_account, publicKey, auxC, errors);
   UpdatePayload(sender_account, e);
   UpdatePayload(sender_account, e);
 end;
 end;
 
 
-function TWIZEnlistAccountForSaleWizard.UpdateOpListForSale(
-  const TargetAccount: TAccount; var SalePrice: int64;
-  var SellerAccount, SignerAccount: TAccount; var NewOwnerPublicKey: TAccountKey;
-  var LockedUntilBlock: cardinal; var errors: ansistring): boolean;
+function TWIZEnlistAccountForSaleWizard.UpdateOpListForSale(const TargetAccount: TAccount; var SalePrice: int64; var SellerAccount, SignerAccount: TAccount; var NewOwnerPublicKey: TAccountKey; var LockedUntilBlock: cardinal; var errors: ansistring): boolean;
 begin
 begin
   Result := False;
   Result := False;
   SalePrice := 0;
   SalePrice := 0;
@@ -226,21 +188,21 @@ begin
         TargetAccount.account) + ' is already enlisted for sale';
         TargetAccount.account) + ' is already enlisted for sale';
       Exit;
       Exit;
     end;
     end;
-    salePrice := Model.SalePrice;
+    salePrice := Model.EnlistAccountForSale.SalePrice;
 
 
-    SignerAccount := Model.SignerAccount;
+    SignerAccount := Model.Signer.SignerAccount;
 
 
-    if (Model.SellerAccount.account = TargetAccount.account) then
+    if (Model.EnlistAccountForSale.SellerAccount.account = TargetAccount.account) then
     begin
     begin
       errors := 'Seller account cannot be same account';
       errors := 'Seller account cannot be same account';
       exit;
       exit;
     end;
     end;
 
 
-    SellerAccount := Model.SellerAccount;
-    if Model.AccountSaleMode = akaPrivateSale then
+    SellerAccount := Model.EnlistAccountForSale.SellerAccount;
+    if Model.EnlistAccountForSale.AccountSaleMode = akaPrivateSale then
     begin
     begin
 
 
-      NewOwnerPublicKey := Model.NewOwnerPublicKey;
+      NewOwnerPublicKey := Model.EnlistAccountForSale.NewOwnerPublicKey;
 
 
       if TAccountComp.EqualAccountKeys(NewOwnerPublicKey,
       if TAccountComp.EqualAccountKeys(NewOwnerPublicKey,
         TargetAccount.accountInfo.accountKey) then
         TargetAccount.accountInfo.accountKey) then
@@ -248,7 +210,7 @@ begin
         errors := 'New public key for private sale is the same public key';
         errors := 'New public key for private sale is the same public key';
         Exit;
         Exit;
       end;
       end;
-      LockedUntilBlock := Model.LockedUntilBlock;
+      LockedUntilBlock := Model.EnlistAccountForSale.LockedUntilBlock;
       if LockedUntilBlock = 0 then
       if LockedUntilBlock = 0 then
       begin
       begin
         errors := 'Insert locking block';
         errors := 'Insert locking block';
@@ -294,21 +256,17 @@ begin
     _signer_n_ops := 0;
     _signer_n_ops := 0;
     operationstxt := '';
     operationstxt := '';
     operation_to_string := '';
     operation_to_string := '';
-    for iAcc := Low(Model.SelectedAccounts) to High(Model.SelectedAccounts) do
+    for iAcc := Low(Model.Account.SelectedAccounts) to High(Model.Account.SelectedAccounts) do
     begin
     begin
       loop_start:
       loop_start:
         op := nil;
         op := nil;
-      account := Model.SelectedAccounts[iAcc];
+      account := Model.Account.SelectedAccounts[iAcc];
       if not UpdatePayload(account, errors) then
       if not UpdatePayload(account, errors) then
-      begin
         raise Exception.Create('Error encoding payload of sender account ' +
         raise Exception.Create('Error encoding payload of sender account ' +
           TAccountComp.AccountNumberToAccountTxtNumber(account.account) + ': ' + errors);
           TAccountComp.AccountNumberToAccountTxtNumber(account.account) + ': ' + errors);
-      end;
       i := TWallet.Keys.IndexOfAccountKey(account.accountInfo.accountKey);
       i := TWallet.Keys.IndexOfAccountKey(account.accountInfo.accountKey);
       if i < 0 then
       if i < 0 then
-      begin
         raise Exception.Create('Sender account private key not found in Wallet');
         raise Exception.Create('Sender account private key not found in Wallet');
-      end;
 
 
       wk := TWallet.Keys.Key[i];
       wk := TWallet.Keys.Key[i];
       dooperation := True;
       dooperation := True;
@@ -320,32 +278,24 @@ begin
 
 
       if not UpdateOpListForSale(account, _salePrice, destAccount,
       if not UpdateOpListForSale(account, _salePrice, destAccount,
         signerAccount, _newOwnerPublicKey, _lockedUntil, errors) then
         signerAccount, _newOwnerPublicKey, _lockedUntil, errors) then
-      begin
         raise Exception.Create(errors);
         raise Exception.Create(errors);
-      end;
       // Special fee account:
       // Special fee account:
       if signerAccount.balance > Model.Fee.DefaultFee then
       if signerAccount.balance > Model.Fee.DefaultFee then
         _fee := Model.Fee.DefaultFee
         _fee := Model.Fee.DefaultFee
       else
       else
         _fee := signerAccount.balance;
         _fee := signerAccount.balance;
-      if Model.AccountSaleMode = akaPublicSale then
-      begin
+      if Model.EnlistAccountForSale.AccountSaleMode = akaPublicSale then
         op := TOpListAccountForSale.CreateListAccountForSale(
         op := TOpListAccountForSale.CreateListAccountForSale(
           signerAccount.account, signerAccount.n_operation + 1 + iAcc,
           signerAccount.account, signerAccount.n_operation + 1 + iAcc,
           account.account, _salePrice, _fee, destAccount.account,
           account.account, _salePrice, _fee, destAccount.account,
-          CT_TECDSA_Public_Nul, 0, wk.PrivateKey, Model.EncodedPayload);
-      end
-      else if Model.AccountSaleMode = akaPrivateSale then
-      begin
+          CT_TECDSA_Public_Nul, 0, wk.PrivateKey, Model.Payload.EncodedBytes)
+      else if Model.EnlistAccountForSale.AccountSaleMode = akaPrivateSale then
         op := TOpListAccountForSale.CreateListAccountForSale(
         op := TOpListAccountForSale.CreateListAccountForSale(
           signerAccount.account, signerAccount.n_operation + 1 + iAcc,
           signerAccount.account, signerAccount.n_operation + 1 + iAcc,
           account.account, _salePrice, _fee, destAccount.account,
           account.account, _salePrice, _fee, destAccount.account,
-          _newOwnerPublicKey, _lockedUntil, wk.PrivateKey, Model.EncodedPayload);
-      end
+          _newOwnerPublicKey, _lockedUntil, wk.PrivateKey, Model.Payload.EncodedBytes)
       else
       else
-      begin
         raise Exception.Create('Invalid Sale type');
         raise Exception.Create('Invalid Sale type');
-      end;
 
 
       if Assigned(op) and (dooperation) then
       if Assigned(op) and (dooperation) then
       begin
       begin
@@ -360,41 +310,32 @@ begin
     if (ops.OperationsCount = 0) then
     if (ops.OperationsCount = 0) then
       raise Exception.Create('No valid operation to execute');
       raise Exception.Create('No valid operation to execute');
 
 
-    if (Length(Model.SelectedAccounts) > 1) then
+    if (Length(Model.Account.SelectedAccounts) > 1) then
     begin
     begin
       auxs := '';
       auxs := '';
       if Application.MessageBox(
       if Application.MessageBox(
-        PChar('Execute ' + IntToStr(Length(Model.SelectedAccounts)) +
+        PChar('Execute ' + IntToStr(Length(Model.Account.SelectedAccounts)) +
         ' operations?' + #10 + 'Operation: ' + operationstxt + #10 +
         ' operations?' + #10 + 'Operation: ' + operationstxt + #10 +
         auxs + 'Total fee: ' + TAccountComp.FormatMoney(_totalfee) +
         auxs + 'Total fee: ' + TAccountComp.FormatMoney(_totalfee) +
         #10 + #10 + 'Note: This operation will be transmitted to the network!'),
         #10 + #10 + 'Note: This operation will be transmitted to the network!'),
         PChar(Application.Title), MB_YESNO + MB_ICONINFORMATION + MB_DEFBUTTON2) <>
         PChar(Application.Title), MB_YESNO + MB_ICONINFORMATION + MB_DEFBUTTON2) <>
         idYes then
         idYes then
-      begin
         Exit;
         Exit;
-      end;
     end
     end
     else
     else
-    begin
-      if Application.MessageBox(PChar('Execute this operation:' +
-        #10 + #10 + operation_to_string + #10 + #10 +
-        'Note: This operation will be transmitted to the network!'),
-        PChar(Application.Title), MB_YESNO + MB_ICONINFORMATION + MB_DEFBUTTON2) <>
-        idYes then
-      begin
-        Exit;
-      end;
-    end;
+    if Application.MessageBox(PChar('Execute this operation:' +
+      #10 + #10 + operation_to_string + #10 + #10 +
+      'Note: This operation will be transmitted to the network!'),
+      PChar(Application.Title), MB_YESNO + MB_ICONINFORMATION + MB_DEFBUTTON2) <>
+      idYes then
+      Exit;
     i := TNode.Node.AddOperations(nil, ops, nil, errors);
     i := TNode.Node.AddOperations(nil, ops, nil, errors);
     if (i = ops.OperationsCount) then
     if (i = ops.OperationsCount) then
     begin
     begin
       operationstxt := 'Successfully executed ' + IntToStr(i) +
       operationstxt := 'Successfully executed ' + IntToStr(i) +
         ' operations!' + #10 + #10 + operation_to_string;
         ' operations!' + #10 + #10 + operation_to_string;
       if i > 1 then
       if i > 1 then
-      begin
-
-        ShowMessage(operationstxt);
-      end
+        ShowMessage(operationstxt)
       else
       else
       begin
       begin
         Application.MessageBox(
         Application.MessageBox(
@@ -413,9 +354,7 @@ begin
       ShowMessage(operationstxt);
       ShowMessage(operationstxt);
     end
     end
     else
     else
-    begin
       raise Exception.Create(errors);
       raise Exception.Create(errors);
-    end;
 
 
 
 
   finally
   finally
@@ -426,8 +365,15 @@ end;
 
 
 constructor TWIZEnlistAccountForSaleWizard.Create(AOwner: TComponent);
 constructor TWIZEnlistAccountForSaleWizard.Create(AOwner: TComponent);
 begin
 begin
-  inherited Create(AOwner, [TWIZEnlistAccountForSale_Start,
-    TWIZEnlistAccountForSale_Confirmation]);
+  inherited Create(AOwner,
+    [
+    TWIZEnlistAccountForSale_ConfirmAccount,
+    TWIZEnlistAccountForSale_SelectOption,
+    TWIZEnlistAccountForSale_EnterSeller,
+    TWIZEnlistAccountForSale_EnterSaleAmount,
+    TWIZEnlistAccountForSale_Confirmation
+    ]
+    );
   TitleText := 'Enlist Account';
   TitleText := 'Enlist Account';
   FinishText := 'Enlist Account';
   FinishText := 'Enlist Account';
 end;
 end;
@@ -442,8 +388,7 @@ begin
   Result := inherited DetermineHasPrevious;
   Result := inherited DetermineHasPrevious;
 end;
 end;
 
 
-function TWIZEnlistAccountForSaleWizard.FinishRequested(
-  out message: ansistring): boolean;
+function TWIZEnlistAccountForSaleWizard.FinishRequested(out message: ansistring): boolean;
 begin
 begin
   // Execute the Enlist Account For Sale Action here
   // Execute the Enlist Account For Sale Action here
   try
   try
@@ -458,8 +403,8 @@ begin
   end;
   end;
 end;
 end;
 
 
-function TWIZEnlistAccountForSaleWizard.CancelRequested(
-  out message: ansistring): boolean;
+function TWIZEnlistAccountForSaleWizard.CancelRequested(out message: ansistring): boolean;
+
 begin
 begin
   Result := True;
   Result := True;
 end;
 end;

+ 4 - 4
src/gui/wizards/operations/UWIZEnlistAccountForSale_List.lfm → src/gui/wizards/operations/UWIZEnlistAccountForSale_ConfirmAccount.lfm

@@ -1,14 +1,14 @@
-object WIZEnlistAccountForSale_List: TWIZEnlistAccountForSale_List
+object WIZEnlistAccountForSale_ConfirmAccount: TWIZEnlistAccountForSale_ConfirmAccount
   Left = 0
   Left = 0
   Height = 253
   Height = 253
   Top = 0
   Top = 0
   Width = 429
   Width = 429
-  Caption = 'WIZEnlistAccountForSale_List'
+  Caption = 'WIZEnlistAccountForSale_ConfirmAccount'
   ClientHeight = 253
   ClientHeight = 253
   ClientWidth = 429
   ClientWidth = 429
-  LCLVersion = '1.8.1.0'
+  LCLVersion = '1.8.2.0'
   Visible = False
   Visible = False
-  object grpTransferAccount: TGroupBox
+  object grpEnlistAccount: TGroupBox
     Left = 6
     Left = 6
     Height = 248
     Height = 248
     Top = 0
     Top = 0

+ 128 - 0
src/gui/wizards/operations/UWIZEnlistAccountForSale_ConfirmAccount.pas

@@ -0,0 +1,128 @@
+unit UWIZEnlistAccountForSale_ConfirmAccount;
+
+{$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, UVisualGrid, UCommon.Data, UCellRenderers, UWizard, UWIZModels;
+
+type
+
+  { TWIZEnlistAccountForSale_ConfirmAccount }
+
+  TWIZEnlistAccountForSale_ConfirmAccount = class(TWizardForm<TWIZOperationsModel>)
+    grpEnlistAccountForSale: TGroupBox;
+    grpEnlistAccount: TGroupBox;
+    paGrid: TPanel;
+  private
+    FEnlistAccountsGrid: TVisualGrid;
+  public
+    procedure OnPresent; override;
+    function Validate(out message: ansistring): boolean; override;
+  end;
+
+
+
+implementation
+
+{$R *.lfm}
+
+uses UAccounts, USettings, UCoreUtils, UDataSources, UCommon, UCommon.UI, Generics.Collections;
+
+type
+
+  { TAccountSenderDataSource }
+
+  TAccountSenderDataSource = class(TAccountsDataSourceBase)
+  private
+    FModel: TWIZOperationsModel;
+  public
+    property Model: TWIZOperationsModel read FModel write FModel;
+    procedure FetchAll(const AContainer: TList<TAccount>); override;
+  end;
+
+{ TWIZEnlistAccountForSale_ConfirmAccount }
+
+procedure TWIZEnlistAccountForSale_ConfirmAccount.OnPresent;
+var
+  Data: TAccountSenderDataSource;
+begin
+  FEnlistAccountsGrid := TVisualGrid.Create(Self);
+  FEnlistAccountsGrid.CanSearch := False;
+  FEnlistAccountsGrid.SortMode := smMultiColumn;
+  FEnlistAccountsGrid.FetchDataInThread := False;
+  FEnlistAccountsGrid.AutoPageSize := True;
+  FEnlistAccountsGrid.SelectionType := stNone;
+  FEnlistAccountsGrid.Options := [vgoColAutoFill, vgoColSizing, vgoSortDirectionAllowNone,
+    vgoAutoHidePaging];
+  with FEnlistAccountsGrid.AddColumn('Account') do
+  begin
+    StretchedToFill := True;
+    Binding := 'AccountNumber';
+    SortBinding := 'AccountNumber';
+    DisplayBinding := 'Account';
+    Width := 100;
+    HeaderFontStyles := [fsBold];
+    DataFontStyles := [fsBold];
+    Filters := SORTABLE_NUMERIC_FILTER;
+  end;
+  with FEnlistAccountsGrid.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(FEnlistAccountsGrid);
+  Data.Model := Model;
+  FEnlistAccountsGrid.DataSource := Data;
+  paGrid.AddControlDockCenter(FEnlistAccountsGrid);
+end;
+
+function TWIZEnlistAccountForSale_ConfirmAccount.Validate(out message: ansistring): boolean;
+var
+  i: integer;
+begin
+  Result := True;
+  for i := Low(model.Account.SelectedAccounts) to High(model.Account.SelectedAccounts) do
+    if TAccountComp.IsAccountForSale(model.Account.SelectedAccounts[i].accountInfo) then
+    begin
+      Result := False;
+      message := 'Account ' + TAccountComp.AccountNumberToAccountTxtNumber(
+        model.Account.SelectedAccounts[i].account) + ' is already enlisted for sale';
+      Exit;
+    end;
+
+  // get signer accounts from selected accounts
+  Model.Signer.SignerCandidates := TCoreTool.GetSignerCandidates(Length(Model.Account.SelectedAccounts), Model.Account.SelectedAccounts);
+
+  if Length(Model.Signer.SignerCandidates) < 1 then
+  begin
+    Result := False;
+    message := 'no valid signer account was found.';
+  end;
+end;
+
+procedure TAccountSenderDataSource.FetchAll(const AContainer: TList<TAccount>);
+var
+  i: integer;
+begin
+  for i := Low(Model.Account.SelectedAccounts) to High(Model.Account.SelectedAccounts) do
+    AContainer.Add(Model.Account.SelectedAccounts[i]);
+end;
+
+
+end.

+ 1 - 0
src/gui/wizards/operations/UWIZEnlistAccountForSale_Confirmation.lfm

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

+ 38 - 33
src/gui/wizards/operations/UWIZEnlistAccountForSale_Confirmation.pas

@@ -13,13 +13,13 @@ interface
 
 
 uses
 uses
   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
-  ExtCtrls, UVisualGrid, UCellRenderers, UCommon.Data, UWizard, UWIZEnlistAccountForSale;
+  ExtCtrls, UVisualGrid, UCellRenderers, UCommon.Data, UWizard, UWIZModels;
 
 
 type
 type
 
 
   { TWIZEnlistAccountForSale_Confirmation }
   { TWIZEnlistAccountForSale_Confirmation }
 
 
-  TWIZEnlistAccountForSale_Confirmation = class(TWizardForm<TWIZEnlistAccountForSaleModel>)
+  TWIZEnlistAccountForSale_Confirmation = class(TWizardForm<TWIZOperationsModel>)
     GroupBox1: TGroupBox;
     GroupBox1: TGroupBox;
     Label1: TLabel;
     Label1: TLabel;
     Label2: TLabel;
     Label2: TLabel;
@@ -27,9 +27,10 @@ type
     lblSellerAcc: TLabel;
     lblSellerAcc: TLabel;
     paGrid: TPanel;
     paGrid: TPanel;
   private
   private
-    FSendersGrid : TVisualGrid;
+    FEnlistAccountsGrid : TVisualGrid;
   public
   public
     procedure OnPresent; override;
     procedure OnPresent; override;
+    procedure OnNext; override;
   end;
   end;
 
 
 
 
@@ -37,7 +38,7 @@ implementation
 
 
 {$R *.lfm}
 {$R *.lfm}
 
 
-uses UAccounts, UDataSources, UCommon, UCommon.UI, Generics.Collections;
+uses UAccounts, UWallet, UUserInterface, UDataSources, UCommon, UCommon.UI, Generics.Collections;
 
 
 type
 type
 
 
@@ -45,11 +46,11 @@ type
 
 
   TAccountSenderDataSource = class(TAccountsDataSourceBase)
   TAccountSenderDataSource = class(TAccountsDataSourceBase)
     private
     private
-      FModel : TWIZEnlistAccountForSaleModel;
+      FModel : TWIZOperationsModel;
     protected
     protected
       function GetColumns : TDataColumns; override;
       function GetColumns : TDataColumns; override;
     public
     public
-      property Model : TWIZEnlistAccountForSaleModel read FModel write FModel;
+      property Model : TWIZOperationsModel read FModel write FModel;
       procedure FetchAll(const AContainer : TList<TAccount>); override;
       procedure FetchAll(const AContainer : TList<TAccount>); override;
       function GetItemField(constref AItem: TAccount; const ABindingName : AnsiString) : Variant; override;
       function GetItemField(constref AItem: TAccount; const ABindingName : AnsiString) : Variant; override;
   end;
   end;
@@ -60,43 +61,50 @@ procedure TWIZEnlistAccountForSale_Confirmation.OnPresent;
 var
 var
   data : TAccountSenderDataSource;
   data : TAccountSenderDataSource;
 begin
 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
+  FEnlistAccountsGrid := TVisualGrid.Create(Self);
+  FEnlistAccountsGrid.CanSearch:= False;
+  FEnlistAccountsGrid.SortMode := smMultiColumn;
+  FEnlistAccountsGrid.FetchDataInThread := False;
+  FEnlistAccountsGrid.AutoPageSize := True;
+  FEnlistAccountsGrid.SelectionType := stNone;
+  FEnlistAccountsGrid.Options := [vgoColAutoFill, vgoColSizing, vgoSortDirectionAllowNone, vgoAutoHidePaging];
+  with FEnlistAccountsGrid.AddColumn('Account') do begin
     Binding := 'Account';
     Binding := 'Account';
     Filters := SORTABLE_NUMERIC_FILTER;
     Filters := SORTABLE_NUMERIC_FILTER;
     Width := 100;
     Width := 100;
     HeaderFontStyles := [fsBold];
     HeaderFontStyles := [fsBold];
     DataFontStyles := [fsBold];
     DataFontStyles := [fsBold];
   end;
   end;
-   with FSendersGrid.AddColumn('Sale Price') do begin
+   with FEnlistAccountsGrid.AddColumn('Sale Price') do begin
     Binding := 'SalePrice';
     Binding := 'SalePrice';
     Filters := SORTABLE_NUMERIC_FILTER;
     Filters := SORTABLE_NUMERIC_FILTER;
     Width := 100;
     Width := 100;
     Renderer := TCellRenderers.PASC;
     Renderer := TCellRenderers.PASC;
   end;
   end;
-  // with FSendersGrid.AddColumn('New Public Key') do begin
-  //  Binding := 'NewPublicKey';
-  //  Filters := SORTABLE_TEXT_FILTER;
-  //  Width := 100;
-  //end;
-  with FSendersGrid.AddColumn('Fee') do begin
+
+  with FEnlistAccountsGrid.AddColumn('Fee') do begin
     Filters := SORTABLE_TEXT_FILTER;
     Filters := SORTABLE_TEXT_FILTER;
     Width := 100;
     Width := 100;
   end;
   end;
 
 
-   data := TAccountSenderDataSource.Create(FSendersGrid);
+   data := TAccountSenderDataSource.Create(FEnlistAccountsGrid);
    data.Model := Model;
    data.Model := Model;
-   FSendersGrid.DataSource := data;
-   paGrid.AddControlDockCenter(FSendersGrid);
-   lblSgnAcc.Caption := TAccountComp.AccountNumberToAccountTxtNumber(Model.SignerAccount.account);
-   lblSellerAcc.Caption := TAccountComp.AccountNumberToAccountTxtNumber(Model.SellerAccount.account);
+   FEnlistAccountsGrid.DataSource := data;
+   paGrid.AddControlDockCenter(FEnlistAccountsGrid);
+   lblSgnAcc.Caption := TAccountComp.AccountNumberToAccountTxtNumber(Model.Signer.SignerAccount.account);
+   lblSellerAcc.Caption := TAccountComp.AccountNumberToAccountTxtNumber(Model.EnlistAccountForSale.SellerAccount.account);
+
+end;
 
 
+procedure TWIZEnlistAccountForSale_Confirmation.OnNext;
+var
+  locked: Boolean;
+begin
+  locked := (NOT TWallet.Keys.HasPassword) OR (NOT TWallet.Keys.IsValidPassword);
+  if locked then
+  begin
+    TUserInterface.UnlockWallet(Self);
+  end;
 end;
 end;
 
 
 { TAccountSenderDataSource }
 { TAccountSenderDataSource }
@@ -106,7 +114,6 @@ begin
   Result := TDataColumns.Create(
   Result := TDataColumns.Create(
     TDataColumn.From('Account'),
     TDataColumn.From('Account'),
     TDataColumn.From('SalePrice'),
     TDataColumn.From('SalePrice'),
-    //TDataColumn.From('NewPublicKey'),
     TDataColumn.From('Fee')
     TDataColumn.From('Fee')
   );
   );
 end;
 end;
@@ -118,11 +125,9 @@ begin
    if ABindingName = 'Account' then
    if ABindingName = 'Account' then
      Result := TAccountComp.AccountNumberToAccountTxtNumber(AItem.account)
      Result := TAccountComp.AccountNumberToAccountTxtNumber(AItem.account)
    else if ABindingName = 'SalePrice' then
    else if ABindingName = 'SalePrice' then
-     Result := TAccountComp.FormatMoney(Model.SalePrice)
-   //else if ABindingName = 'NewPublicKey' then
-   //  Result := Model.NewPublicKey
+     Result := TAccountComp.FormatMoney(Model.EnlistAccountForSale.SalePrice)
      else if ABindingName = 'Fee' then
      else if ABindingName = 'Fee' then
-     Result := TAccountComp.FormatMoney(Model.Fee.DefaultFee)
+     Result := TAccountComp.FormatMoney(Model.Fee.SingleOperationFee)
    else raise Exception.Create(Format('Field not found [%s]', [ABindingName]));
    else raise Exception.Create(Format('Field not found [%s]', [ABindingName]));
 end;
 end;
 
 
@@ -131,9 +136,9 @@ procedure TAccountSenderDataSource.FetchAll(const AContainer : TList<TAccount>);
 var
 var
   i: Integer;
   i: Integer;
 begin
 begin
-  for i := Low(Model.SelectedAccounts) to High(Model.SelectedAccounts) do
+  for i := Low(Model.Account.SelectedAccounts) to High(Model.Account.SelectedAccounts) do
   begin
   begin
-    AContainer.Add( Model.SelectedAccounts[i] );
+    AContainer.Add( Model.Account.SelectedAccounts[i] );
   end;
   end;
 end;
 end;
 
 

+ 36 - 0
src/gui/wizards/operations/UWIZEnlistAccountForSale_EnterLockingBlock.lfm

@@ -0,0 +1,36 @@
+object WIZEnlistAccountForSale_EnterLockingBlock: TWIZEnlistAccountForSale_EnterLockingBlock
+  Left = 0
+  Height = 253
+  Top = 40
+  Width = 429
+  ActiveControl = edtBlockLock
+  Caption = 'WIZEnlistAccountForSale_EnterLockingBlock'
+  ClientHeight = 253
+  ClientWidth = 429
+  Visible = False
+  object gbLockBlock: TGroupBox
+    Left = 16
+    Height = 232
+    Top = 8
+    Width = 400
+    Caption = 'Enter Locking Block'
+    ClientHeight = 212
+    ClientWidth = 396
+    TabOrder = 0
+    object lblBlockLock: TLabel
+      Left = 8
+      Height = 15
+      Top = 8
+      Width = 378
+      Caption = 'Please enter the block at which this sale will be allowed to succeed from'
+      ParentColor = False
+    end
+    object edtBlockLock: TEdit
+      Left = 8
+      Height = 23
+      Top = 48
+      Width = 152
+      TabOrder = 0
+    end
+  end
+end

+ 63 - 0
src/gui/wizards/operations/UWIZEnlistAccountForSale_EnterLockingBlock.pas

@@ -0,0 +1,63 @@
+unit UWIZEnlistAccountForSale_EnterLockingBlock;
+
+{$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, UWizard, UWIZModels, UWIZEnlistAccountForSale_EnterSeller;
+
+type
+
+  { TWIZEnlistAccountForSale_EnterLockingBlock }
+
+  TWIZEnlistAccountForSale_EnterLockingBlock = class(TWizardForm<TWIZOperationsModel>)
+    edtBlockLock: TEdit;
+    gbLockBlock: TGroupBox;
+    lblBlockLock: TLabel;
+  public
+    procedure OnPresent; override;
+    function Validate(out message: ansistring): boolean; override;
+  end;
+
+
+implementation
+
+{$R *.lfm}
+
+uses
+  UAccounts;
+
+{ TWIZEnlistAccountForSale_EnterLockingBlock }
+
+procedure TWIZEnlistAccountForSale_EnterLockingBlock.OnPresent;
+begin
+  edtBlockLock.SetFocus;
+end;
+
+function TWIZEnlistAccountForSale_EnterLockingBlock.Validate(out message: ansistring): boolean;
+var
+  LockedUntilBlock: cardinal;
+begin
+  Result := True;
+
+  LockedUntilBlock := StrToIntDef(edtBlockLock.Text, 0);
+  if LockedUntilBlock = 0 then
+  begin
+    message := 'Insert locking block';
+    Result := False;
+    exit;
+  end;
+  Model.EnlistAccountForSale.LockedUntilBlock := LockedUntilBlock;
+
+end;
+
+end.

+ 36 - 0
src/gui/wizards/operations/UWIZEnlistAccountForSale_EnterPublicKey.lfm

@@ -0,0 +1,36 @@
+object WIZEnlistAccountForSale_EnterPublicKey: TWIZEnlistAccountForSale_EnterPublicKey
+  Left = 0
+  Height = 253
+  Top = 40
+  Width = 429
+  ActiveControl = mmoPublicKey
+  Caption = 'WIZEnlistAccountForSale_EnterPublicKey'
+  ClientHeight = 253
+  ClientWidth = 429
+  Visible = False
+  object gbTransaction: TGroupBox
+    Left = 16
+    Height = 232
+    Top = 8
+    Width = 400
+    Caption = 'Enter Public Key'
+    ClientHeight = 212
+    ClientWidth = 396
+    TabOrder = 0
+    object lblPublicKey: TLabel
+      Left = 8
+      Height = 15
+      Top = 8
+      Width = 377
+      Caption = 'Please Enter the Public Key of the account you wish to make the sale to.'
+      ParentColor = False
+    end
+    object mmoPublicKey: TMemo
+      Left = 8
+      Height = 144
+      Top = 40
+      Width = 378
+      TabOrder = 0
+    end
+  end
+end

+ 79 - 0
src/gui/wizards/operations/UWIZEnlistAccountForSale_EnterPublicKey.pas

@@ -0,0 +1,79 @@
+unit UWIZEnlistAccountForSale_EnterPublicKey;
+
+{$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, UWizard, UWIZModels, UWIZEnlistAccountForSale_EnterLockingBlock;
+
+type
+
+  { TWIZEnlistAccountForSale_EnterPublicKey }
+
+  TWIZEnlistAccountForSale_EnterPublicKey = class(TWizardForm<TWIZOperationsModel>)
+    gbTransaction: TGroupBox;
+    lblBlockLock: TLabel;
+    lblPublicKey: TLabel;
+    mmoPublicKey: TMemo;
+  public
+    procedure OnPresent; override;
+    procedure OnNext; override;
+    function Validate(out message: ansistring): boolean; override;
+  end;
+
+
+implementation
+
+{$R *.lfm}
+
+uses
+  UAccounts;
+
+{ TWIZEnlistAccountForSale_EnterPublicKey }
+
+procedure TWIZEnlistAccountForSale_EnterPublicKey.OnPresent;
+begin
+  mmoPublicKey.SetFocus;
+end;
+
+procedure TWIZEnlistAccountForSale_EnterPublicKey.OnNext;
+begin
+   UpdatePath(ptInject, [TWIZEnlistAccountForSale_EnterLockingBlock]);
+end;
+
+function TWIZEnlistAccountForSale_EnterPublicKey.Validate(out message: ansistring): boolean;
+var
+  i: integer;
+begin
+  Result := True;
+
+  if not TAccountComp.AccountKeyFromImport(mmoPublicKey.Text,
+    Model.EnlistAccountForSale.NewOwnerPublicKey, message) then
+  begin
+    message := 'Public key: ' + message;
+    Result := False;
+    exit;
+
+  end;
+
+  for i := Low(Model.Account.SelectedAccounts) to High(Model.Account.SelectedAccounts) do
+    if TAccountComp.EqualAccountKeys(Model.EnlistAccountForSale.NewOwnerPublicKey,
+      Model.Account.SelectedAccounts[i].accountInfo.accountKey) then
+    begin
+      message := 'New public key for private sale is the same public key';
+      Result := False;
+      Exit;
+    end;
+
+end;
+
+end.

+ 52 - 0
src/gui/wizards/operations/UWIZEnlistAccountForSale_EnterSaleAmount.lfm

@@ -0,0 +1,52 @@
+object WIZEnlistAccountForSale_EnterSaleAmount: TWIZEnlistAccountForSale_EnterSaleAmount
+  Left = 0
+  Height = 253
+  Top = 0
+  Width = 429
+  ActiveControl = edtAmt
+  Caption = 'WIZEnlistAccountForSale_EnterSaleAmount'
+  ClientHeight = 253
+  ClientWidth = 429
+  Visible = False
+  object gbSaleAmount: TGroupBox
+    Left = 16
+    Height = 232
+    Top = 8
+    Width = 400
+    Caption = 'Sale Amount'
+    ClientHeight = 212
+    ClientWidth = 396
+    TabOrder = 0
+    object edtAmt: TEdit
+      Left = 8
+      Height = 23
+      Top = 40
+      Width = 160
+      TabOrder = 0
+    end
+    object lblSaleAmountNotice: TLabel
+      Left = 8
+      Height = 15
+      Top = 7
+      Width = 293
+      Caption = 'Please enter the amount you wish to sell EACH PASA at.'
+      ParentColor = False
+    end
+    object chkChooseFee: TCheckBox
+      Left = 8
+      Height = 19
+      Top = 80
+      Width = 226
+      Caption = 'Let me choose fee''s for this transaction'
+      TabOrder = 1
+    end
+    object chkAttachPayload: TCheckBox
+      Left = 8
+      Height = 19
+      Top = 110
+      Width = 303
+      Caption = 'I want to attach a message payload to this transaction'
+      TabOrder = 2
+    end
+  end
+end

+ 118 - 0
src/gui/wizards/operations/UWIZEnlistAccountForSale_EnterSaleAmount.pas

@@ -0,0 +1,118 @@
+unit UWIZEnlistAccountForSale_EnterSaleAmount;
+
+{$mode delphi}
+{$modeswitch nestedprocvars}
+
+{ Copyright (c) 2018 Sphere 10 Software (http://www.sphere10.com/)
+
+  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
+
+uses
+  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
+  ExtCtrls, Buttons, UCommon, UCommon.Collections, UWallet,
+  UFRMAccountSelect, UNode, UWizard, UWIZOperationFee_Custom, UWIZOperationPayload_Encryption, UWIZOperationSigner_Select,
+  UWIZEnlistAccountForSale_Confirmation, UWIZModels;
+
+type
+
+  { TWIZEnlistAccountForSale_EnterSaleAmount }
+
+  TWIZEnlistAccountForSale_EnterSaleAmount = class(TWizardForm<TWIZOperationsModel>)
+    chkChooseFee: TCheckBox;
+    chkAttachPayload: TCheckBox;
+    edtAmt: TEdit;
+    gbSaleAmount: TGroupBox;
+    lblSaleAmountNotice: TLabel;
+    procedure UpdateUI();
+
+
+
+  public
+    procedure OnPresent; override;
+    procedure OnNext; override;
+    function Validate(out message: ansistring): boolean; override;
+  end;
+
+
+implementation
+
+{$R *.lfm}
+
+uses
+  UAccounts, UUserInterface, USettings;
+
+{ TWIZSendPASC_EnterQuantity }
+
+procedure TWIZEnlistAccountForSale_EnterSaleAmount.UpdateUI();
+begin
+  edtAmt.Text := TAccountComp.FormatMoney(0);
+end;
+
+procedure TWIZEnlistAccountForSale_EnterSaleAmount.OnPresent;
+begin
+  UpdateUI();
+  if Length(Model.Account.SelectedAccounts) > 1 then
+  begin
+    chkChooseFee.Checked := True;
+    chkChooseFee.Enabled := False;
+  end;
+  if edtAmt.Enabled then
+    edtAmt.SetFocus;
+end;
+
+procedure TWIZEnlistAccountForSale_EnterSaleAmount.OnNext;
+var
+  amount: int64;
+begin
+  Model.Payload.HasPayload := chkAttachPayload.Checked;
+  TAccountComp.TxtToMoney(edtAmt.Text, Model.EnlistAccountForSale.SalePrice);
+
+  if chkChooseFee.Checked then
+    UpdatePath(ptReplaceAllNext, [TWIZOperationFee_Custom, TWIZEnlistAccountForSale_Confirmation])
+  else
+  begin
+    Model.Fee.SingleOperationFee := TSettings.DefaultFee;
+    if Model.Payload.HasPayload then
+      UpdatePath(ptReplaceAllNext, [TWIZOperationPayload_Encryption, TWIZEnlistAccountForSale_Confirmation])
+    else if Length(Model.Account.SelectedAccounts) > 1 then
+      UpdatePath(ptReplaceAllNext, [TWIZOperationSigner_Select, TWIZEnlistAccountForSale_Confirmation])
+    else
+    begin
+      Model.Signer.SignerAccount := Model.Account.SelectedAccounts[0];
+      Model.Signer.OperationSigningMode := akaPrimary;
+    end;
+  end;
+
+end;
+
+function TWIZEnlistAccountForSale_EnterSaleAmount.Validate(out message: ansistring): boolean;
+var
+  amount: int64;
+begin
+  Result := True;
+
+  if not TAccountComp.TxtToMoney(edtAmt.Text, amount) then
+  begin
+    message := 'Invalid amount (' + edtAmt.Text + ')';
+    Result := False;
+    Exit;
+  end;
+
+  if amount < 1 then
+  begin
+    message := 'Invalid amount (' + edtAmt.Text + '), you must sell for an amount greater than zero';
+    Result := False;
+    Exit;
+  end;
+
+end;
+
+end.

+ 53 - 87
src/gui/wizards/operations/UWIZEnlistAccountForSale_Transaction.lfm → src/gui/wizards/operations/UWIZEnlistAccountForSale_EnterSeller.lfm

@@ -1,65 +1,34 @@
-object WIZEnlistAccountForSale_Transaction: TWIZEnlistAccountForSale_Transaction
+object WIZEnlistAccountForSale_EnterSeller: TWIZEnlistAccountForSale_EnterSeller
   Left = 0
   Left = 0
   Height = 253
   Height = 253
-  Top = 40
+  Top = 0
   Width = 429
   Width = 429
-  ActiveControl = cbSignerAccount
-  Caption = 'WIZEnlistAccountForSale_Transaction'
+  ActiveControl = edtSellerAcc
+  Caption = 'WIZEnlistAccountForSale_EnterSeller'
   ClientHeight = 253
   ClientHeight = 253
   ClientWidth = 429
   ClientWidth = 429
-  LCLVersion = '1.8.2.0'
   Visible = False
   Visible = False
-  object gbTransaction: TGroupBox
-    Left = 24
-    Height = 192
-    Top = 40
-    Width = 384
-    Caption = 'Sale Transaction'
-    ClientHeight = 172
-    ClientWidth = 380
+  object gbSeller: TGroupBox
+    Left = 16
+    Height = 232
+    Top = 8
+    Width = 398
+    Caption = 'Seller Account'
+    ClientHeight = 212
+    ClientWidth = 394
     TabOrder = 0
     TabOrder = 0
-    object cbSignerAccount: TComboBox
+    object edtSellerAcc: TEdit
       Left = 8
       Left = 8
       Height = 23
       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 lblSalePrice: TLabel
-      Left = 8
-      Height = 15
-      Top = 48
-      Width = 50
-      Caption = 'Sale Price'
-      ParentColor = False
-    end
-    object edtSalePrice: TEdit
-      Left = 8
-      Height = 23
-      Top = 74
+      Top = 40
       Width = 136
       Width = 136
-      TabOrder = 1
+      OnChange = edtSellerAccChange
+      TabOrder = 0
     end
     end
     object btnSearch: TSpeedButton
     object btnSearch: TSpeedButton
-      Left = 345
+      Left = 152
       Height = 22
       Height = 22
-      Top = 75
+      Top = 41
       Width = 23
       Width = 23
       Glyph.Data = {
       Glyph.Data = {
         36040000424D3604000000000000360000002800000010000000100000000100
         36040000424D3604000000000000360000002800000010000000100000000100
@@ -99,53 +68,50 @@ object WIZEnlistAccountForSale_Transaction: TWIZEnlistAccountForSale_Transaction
       }
       }
       OnClick = btnSearchClick
       OnClick = btnSearchClick
     end
     end
-    object lblOpFee: TLabel
+    object lblDestNotice: TLabel
       Left = 8
       Left = 8
       Height = 15
       Height = 15
-      Top = 112
-      Width = 74
-      Caption = 'Operation Fee'
+      Top = 8
+      Width = 380
+      Caption = 'Please enter the seller account that will receive the payments for the sale'
       ParentColor = False
       ParentColor = False
+      ParentFont = False
     end
     end
-    object edtOpFee: TEdit
+    object lblSellerAccNumber: TLabel
       Left = 8
       Left = 8
-      Height = 23
-      Top = 136
-      Width = 360
-      TabOrder = 2
+      Height = 15
+      Top = 80
+      Width = 126
+      Caption = 'Seller Account Number:'
+      ParentColor = False
+      ParentFont = False
     end
     end
-    object edtSellerAccount: TEdit
-      Left = 200
-      Height = 23
-      Top = 74
-      Width = 136
-      TabOrder = 3
+    object lblSellerAccNumberName: TLabel
+      Left = 8
+      Height = 15
+      Top = 108
+      Width = 161
+      Caption = 'Seller Account Number Name:'
+      ParentColor = False
+      ParentFont = False
     end
     end
-    object lblSellerAccount: TLabel
-      Left = 200
+    object lblSellerAccNumberValue: TLabel
+      Left = 224
       Height = 15
       Height = 15
-      Top = 48
-      Width = 76
-      Caption = 'Seller Account'
+      Top = 80
+      Width = 92
+      Caption = 'Account Number'
       ParentColor = False
       ParentColor = False
+      ParentFont = False
+    end
+    object lblSellerAccNumberNameValue: TLabel
+      Left = 224
+      Height = 15
+      Top = 108
+      Width = 121
+      Caption = 'AccountNumberName'
+      ParentColor = False
+      ParentFont = False
     end
     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
 end
 end

+ 159 - 0
src/gui/wizards/operations/UWIZEnlistAccountForSale_EnterSeller.pas

@@ -0,0 +1,159 @@
+unit UWIZEnlistAccountForSale_EnterSeller;
+
+{$mode delphi}
+{$modeswitch nestedprocvars}
+
+{ Copyright (c) 2018 Sphere 10 Software (http://www.sphere10.com/)
+
+  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
+
+uses
+  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
+  ExtCtrls, Buttons, UCommon, UCommon.Collections, UWallet,
+  UFRMAccountSelect, UNode, UWizard, UWIZModels;
+
+type
+
+  { TWIZEnlistAccountForSale_EnterSeller }
+
+  TWIZEnlistAccountForSale_EnterSeller = class(TWizardForm<TWIZOperationsModel>)
+    edtSellerAcc: TEdit;
+    gbSeller: TGroupBox;
+    lblSellerAccNumber: TLabel;
+    lblSellerAccNumberValue: TLabel;
+    lblSellerAccNumberName: TLabel;
+    lblSellerAccNumberNameValue: TLabel;
+    lblDestNotice: TLabel;
+    btnSearch: TSpeedButton;
+    procedure btnSearchClick(Sender: TObject);
+    procedure edtSellerAccChange(Sender: TObject);
+    procedure UpdateUI();
+
+
+
+  public
+    procedure OnPresent; override;
+    procedure OnNext; override;
+    function Validate(out message: ansistring): boolean; override;
+  end;
+
+
+implementation
+
+{$R *.lfm}
+
+uses
+  UAccounts, UUserInterface, USettings;
+
+{ TWIZEnlistAccountForSale_EnterSeller }
+
+procedure TWIZEnlistAccountForSale_EnterSeller.edtSellerAccChange(Sender: TObject);
+begin
+  UpdateUI();
+end;
+
+procedure TWIZEnlistAccountForSale_EnterSeller.UpdateUI();
+var
+  tempAcc: TAccount;
+  c: cardinal;
+begin
+  if TAccountComp.AccountTxtNumberToAccountNumber(edtSellerAcc.Text, c) then
+  begin
+    if (c < 0) or (c >= TNode.Node.Bank.AccountsCount) then
+    begin
+      lblSellerAccNumberValue.Caption := 'unknown';
+      lblSellerAccNumberNameValue.Caption := 'unknown';
+      Exit;
+    end;
+    tempAcc := TNode.Node.Operations.SafeBoxTransaction.account(c);
+    lblSellerAccNumberValue.Caption := edtSellerAcc.Text;
+    lblSellerAccNumberNameValue.Caption := tempAcc.Name;
+  end
+  else
+  begin
+    lblSellerAccNumberValue.Caption := 'unknown';
+    lblSellerAccNumberNameValue.Caption := 'unknown';
+  end;
+
+end;
+
+procedure TWIZEnlistAccountForSale_EnterSeller.OnPresent;
+begin
+  UpdateUI();
+  edtSellerAcc.SetFocus;
+end;
+
+procedure TWIZEnlistAccountForSale_EnterSeller.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 := edtSellerAcc.Tag;
+    if TAccountComp.AccountTxtNumberToAccountNumber(edtSellerAcc.Text, c) then
+      F.DefaultAccount := c;
+    F.AllowSelect := True;
+    if F.ShowModal = mrOk then
+      edtSellerAcc.Text := TAccountComp.AccountNumberToAccountTxtNumber(F.GetSelected);
+  finally
+    F.Free;
+  end;
+end;
+
+
+procedure TWIZEnlistAccountForSale_EnterSeller.OnNext;
+var
+  c: cardinal;
+  aa: TAccount;
+begin
+  TAccountComp.AccountTxtNumberToAccountNumber(edtSellerAcc.Text, c);
+  Model.SendPASC.DestinationAccount := TNode.Node.Operations.SafeBoxTransaction.account(c);
+end;
+
+function TWIZEnlistAccountForSale_EnterSeller.Validate(out message: ansistring): boolean;
+var
+  i: integer;
+  c: cardinal;
+begin
+  Result := True;
+
+  if not (TAccountComp.AccountTxtNumberToAccountNumber(edtSellerAcc.Text, c)) then
+  begin
+    message := 'Invalid seller account (' + edtSellerAcc.Text + ')';
+    Result := False;
+    Exit;
+  end;
+
+  if (c < 0) or (c >= TNode.Node.Bank.AccountsCount) then
+  begin
+    message := 'Invalid seller account (' +
+      TAccountComp.AccountNumberToAccountTxtNumber(c) + ')';
+    Result := False;
+    Exit;
+  end;
+
+  for i := Low(Model.Account.SelectedAccounts) to High(Model.Account.SelectedAccounts) do
+    if (Model.Account.SelectedAccounts[i].Account = c) then
+    begin
+      message := 'Seller account cannot be same account';
+      Result := False;
+      Exit;
+    end;
+
+  Model.EnlistAccountForSale.SellerAccount := TNode.Node.Operations.SafeBoxTransaction.account(c);
+
+end;
+
+end.

+ 0 - 141
src/gui/wizards/operations/UWIZEnlistAccountForSale_List.pas

@@ -1,141 +0,0 @@
-unit UWIZEnlistAccountForSale_List;
-
-{$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, UVisualGrid, UCommon.Data, UCellRenderers,
-  UWizard, UWIZEnlistAccountForSale, UWIZEnlistAccountForSale_Transaction, UWIZEnlistAccountForSale_PrivateSaleConfig,
-  UWIZEnlistAccountForSale_Confirmation;
-
-type
-
-  { TWIZEnlistAccountForSale_List }
-
-  TWIZEnlistAccountForSale_List = class(TWizardForm<TWIZEnlistAccountForSaleModel>)
-    grpEnlistAccountForSale: TGroupBox;
-    grpTransferAccount: TGroupBox;
-    paGrid: TPanel;
-  private
-    FSendersGrid: TVisualGrid;
-  public
-    procedure OnPresent; override;
-    procedure OnNext; override;
-    function Validate(out message: ansistring): boolean; override;
-  end;
-
-
-
-implementation
-
-{$R *.lfm}
-
-uses UAccounts, USettings, UDataSources, UCommon, UCommon.UI, Generics.Collections;
-
-type
-
-  { TAccountSenderDataSource }
-
-  TAccountSenderDataSource = class(TAccountsDataSourceBase)
-  private
-    FModel: TWIZEnlistAccountForSaleModel;
-  public
-    property Model: TWIZEnlistAccountForSaleModel read FModel write FModel;
-    procedure FetchAll(const AContainer: TList<TAccount>); override;
-  end;
-
-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;
-
-{ TWIZEnlistAccountForSale_List }
-
-procedure TWIZEnlistAccountForSale_List.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;
-  FSendersGrid.DataSource := Data;
-  paGrid.AddControlDockCenter(FSendersGrid);
-end;
-
-procedure TWIZEnlistAccountForSale_List.OnNext;
-begin
-  case Model.AccountSaleMode of
-  akaPublicSale:
-    begin
-      UpdatePath(ptReplaceAllNext, [TWIZEnlistAccountForSale_Transaction, TWIZEnlistAccountForSale_Confirmation]);
-    end;
-
-   akaPrivateSale:
-    begin
-      UpdatePath(ptReplaceAllNext, [TWIZEnlistAccountForSale_PrivateSaleConfig, TWIZEnlistAccountForSale_Confirmation]);
-    end;
-
-  end;
-end;
-
-function TWIZEnlistAccountForSale_List.Validate(out message: ansistring): boolean;
-var
-  i: Integer;
-begin
-  Result := True;
-   for i := Low(model.SelectedAccounts) to High(model.SelectedAccounts) do
-  begin
-    if TAccountComp.IsAccountForSale(model.SelectedAccounts[i].accountInfo) then
-    begin
-      Result := False;
-      message := 'Account ' + TAccountComp.AccountNumberToAccountTxtNumber(
-        model.SelectedAccounts[i].account) + ' is already enlisted for sale';
-      Exit;
-    end;
-  end;
-end;
-
-end.

+ 0 - 50
src/gui/wizards/operations/UWIZEnlistAccountForSale_PrivateSaleConfig.lfm

@@ -1,50 +0,0 @@
-object WIZEnlistAccountForSale_PrivateSaleConfig: TWIZEnlistAccountForSale_PrivateSaleConfig
-  Left = 0
-  Height = 253
-  Top = 40
-  Width = 429
-  Caption = 'WIZEnlistAccountForSale_PrivateSaleConfig'
-  ClientHeight = 253
-  ClientWidth = 429
-  Visible = False
-  object gbTransaction: TGroupBox
-    Left = 24
-    Height = 216
-    Top = 16
-    Width = 384
-    Caption = 'Private Sale Config'
-    ClientHeight = 196
-    ClientWidth = 380
-    TabOrder = 0
-    object lblBlockLock: TLabel
-      Left = 8
-      Height = 15
-      Top = 8
-      Width = 98
-      Caption = 'Locked Until Block'
-      ParentColor = False
-    end
-    object edtBlockLock: TEdit
-      Left = 8
-      Height = 23
-      Top = 40
-      Width = 360
-      TabOrder = 0
-    end
-    object lblPublicKey: TLabel
-      Left = 8
-      Height = 15
-      Top = 104
-      Width = 120
-      Caption = 'New Owner Public Key'
-      ParentColor = False
-    end
-    object edtPublicKey: TEdit
-      Left = 8
-      Height = 23
-      Top = 136
-      Width = 360
-      TabOrder = 1
-    end
-  end
-end

+ 0 - 92
src/gui/wizards/operations/UWIZEnlistAccountForSale_PrivateSaleConfig.pas

@@ -1,92 +0,0 @@
-unit UWIZEnlistAccountForSale_PrivateSaleConfig;
-
-{$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, UWizard, UWIZEnlistAccountForSale,
-  UWIZEnlistAccountForSale_Transaction,
-  UWIZEnlistAccountForSale_Confirmation;
-
-type
-
-  { TWIZEnlistAccountForSale_PrivateSaleConfig }
-
-  TWIZEnlistAccountForSale_PrivateSaleConfig =
-  class(TWizardForm<TWIZEnlistAccountForSaleModel>)
-    edtBlockLock: TEdit;
-    edtPublicKey: TEdit;
-    gbTransaction: TGroupBox;
-    lblBlockLock: TLabel;
-    lblPublicKey: TLabel;
-  public
-    procedure OnNext; override;
-    function Validate(out message: ansistring): boolean; override;
-  end;
-
-
-implementation
-
-{$R *.lfm}
-
-uses
-  UAccounts;
-
-{ TWIZEnlistAccountForSale_PrivateSaleConfig }
-
-procedure TWIZEnlistAccountForSale_PrivateSaleConfig.OnNext;
-begin
-  Model.NewPublicKey := edtPublicKey.Text;
-  UpdatePath(ptReplaceAllNext, [TWIZEnlistAccountForSale_Transaction,
-    TWIZEnlistAccountForSale_Confirmation]);
-end;
-
-function TWIZEnlistAccountForSale_PrivateSaleConfig.Validate(
-  out message: ansistring): boolean;
-var
-  c, LockedUntilBlock: cardinal;
-  i: integer;
-begin
-  Result := True;
-
-  LockedUntilBlock := StrToIntDef(edtBlockLock.Text, 0);
-  if LockedUntilBlock = 0 then
-  begin
-    message := 'Insert locking block';
-    Result := False;
-    exit;
-  end;
-  Model.LockedUntilBlock := LockedUntilBlock;
-
-  if not TAccountComp.AccountKeyFromImport(edtPublicKey.Text,
-    Model.NewOwnerPublicKey, message) then
-  begin
-    message := 'Public key: ' + message;
-    Result := False;
-    exit;
-
-  end;
-
-  for i := Low(Model.SelectedAccounts) to High(Model.SelectedAccounts) do
-  begin
-    if TAccountComp.EqualAccountKeys(Model.NewOwnerPublicKey,
-      Model.SelectedAccounts[i].accountInfo.accountKey) then
-    begin
-      message := 'New public key for private sale is the same public key';
-      Result := False;
-      Exit;
-    end;
-  end;
-
-end;
-
-end.

+ 3 - 3
src/gui/wizards/operations/UWIZEnlistAccountForSale_Start.lfm → src/gui/wizards/operations/UWIZEnlistAccountForSale_SelectOption.lfm

@@ -1,10 +1,10 @@
-object WIZEnlistAccountForSale_Start: TWIZEnlistAccountForSale_Start
+object WIZEnlistAccountForSale_SelectOption: TWIZEnlistAccountForSale_SelectOption
   Left = 0
   Left = 0
   Height = 253
   Height = 253
   Top = 0
   Top = 0
   Width = 429
   Width = 429
   ActiveControl = rbPublicSale
   ActiveControl = rbPublicSale
-  Caption = 'WIZEnlistAccountForSale_Start'
+  Caption = 'WIZEnlistAccountForSale_SelectOption'
   ClientHeight = 253
   ClientHeight = 253
   ClientWidth = 429
   ClientWidth = 429
   Visible = False
   Visible = False
@@ -59,7 +59,7 @@ object WIZEnlistAccountForSale_Start: TWIZEnlistAccountForSale_Start
     Width = 350
     Width = 350
     Anchors = [akTop, akLeft, akRight]
     Anchors = [akTop, akLeft, akRight]
     AutoSize = False
     AutoSize = False
-    Caption = 'This account is only available to the specified public key for sale.'
+    Caption = 'This account is only available for sale to the specified public key.'
     ParentColor = False
     ParentColor = False
     WordWrap = True
     WordWrap = True
   end
   end

+ 11 - 14
src/gui/wizards/operations/UWIZEnlistAccountForSale_Start.pas → src/gui/wizards/operations/UWIZEnlistAccountForSale_SelectOption.pas

@@ -1,4 +1,4 @@
-unit UWIZEnlistAccountForSale_Start;
+unit UWIZEnlistAccountForSale_SelectOption;
 
 
 {$mode delphi}
 {$mode delphi}
 {$modeswitch nestedprocvars}
 {$modeswitch nestedprocvars}
@@ -13,14 +13,13 @@ interface
 
 
 uses
 uses
   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
-  ExtCtrls, UWizard, UWIZEnlistAccountForSale, UWIZEnlistAccountForSale_List,
-  UWIZEnlistAccountForSale_Confirmation;
+  ExtCtrls, UWizard, UWIZModels, UWIZEnlistAccountForSale_EnterPublicKey;
 
 
 type
 type
 
 
-  { TWIZEnlistAccountForSale_Start }
+  { TWIZEnlistAccountForSale_SelectOption }
 
 
-  TWIZEnlistAccountForSale_Start = class(TWizardForm<TWIZEnlistAccountForSaleModel>)
+  TWIZEnlistAccountForSale_SelectOption = class(TWizardForm<TWIZOperationsModel>)
     grpEnlistAccountForSale: TGroupBox;
     grpEnlistAccountForSale: TGroupBox;
     Label1: TLabel;
     Label1: TLabel;
     Label2: TLabel;
     Label2: TLabel;
@@ -39,20 +38,18 @@ implementation
 
 
 uses UAccounts, USettings, UDataSources, UCommon, UCommon.UI, Generics.Collections;
 uses UAccounts, USettings, UDataSources, UCommon, UCommon.UI, Generics.Collections;
 
 
-{ TWIZEnlistAccountForSale_Start }
+{ TWIZEnlistAccountForSale_SelectOption }
 
 
-procedure TWIZEnlistAccountForSale_Start.OnNext;
+procedure TWIZEnlistAccountForSale_SelectOption.OnNext;
 begin
 begin
-  if rbPublicSale.Checked = True then
-  begin
-    Model.AccountSaleMode := akaPublicSale;
-  end
+  if rbPublicSale.Checked then
+    Model.EnlistAccountForSale.AccountSaleMode := akaPublicSale
   else
   else
   begin
   begin
-    Model.AccountSaleMode := akaPrivateSale;
+    Model.EnlistAccountForSale.AccountSaleMode := akaPrivateSale;
+    UpdatePath(ptInject, [TWIZEnlistAccountForSale_EnterPublicKey]);
   end;
   end;
-  UpdatePath(ptReplaceAllNext, [TWIZEnlistAccountForSale_List,
-    TWIZEnlistAccountForSale_Confirmation]);
+
 end;
 end;
 
 
 end.
 end.

+ 0 - 199
src/gui/wizards/operations/UWIZEnlistAccountForSale_Transaction.pas

@@ -1,199 +0,0 @@
-unit UWIZEnlistAccountForSale_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, UWIZEnlistAccountForSale,
-  UWIZEnlistAccountForSale_TransactionPayload,
-  UWIZEnlistAccountForSale_Confirmation;
-
-type
-
-  { TWIZEnlistAccountForSale_Transaction }
-
-  TWIZEnlistAccountForSale_Transaction =
-    class(TWizardForm<TWIZEnlistAccountForSaleModel>)
-    btnSearch: TSpeedButton;
-    cbSignerAccount: TComboBox;
-    edtSalePrice: TEdit;
-    edtSellerAccount: TEdit;
-    edtOpFee: TEdit;
-    gbTransaction: TGroupBox;
-    lblBalance: TLabel;
-    lblSalePrice: TLabel;
-    lblSellerAccount: TLabel;
-    lblOpFee: TLabel;
-    lblTotalBalances: TLabel;
-    lblTotalBalanceValue: TLabel;
-    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;
-
-{ TWIZEnlistAccountForSale_Transaction }
-
-procedure TWIZEnlistAccountForSale_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 TWIZEnlistAccountForSale_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 := edtSellerAccount.Tag;
-    if TAccountComp.AccountTxtNumberToAccountNumber(edtSellerAccount.Text, c) then
-      F.DefaultAccount := c;
-    F.AllowSelect := True;
-    if F.ShowModal = mrOk then
-    begin
-      edtSellerAccount.Text := TAccountComp.AccountNumberToAccountTxtNumber(F.GetSelected);
-    end;
-  finally
-    F.Free;
-  end;
-end;
-
-procedure TWIZEnlistAccountForSale_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 := Low(Model.SelectedAccounts) 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)]);
-  edtOpFee.Text := TAccountComp.FormatMoney(TSettings.DefaultFee);
-  edtSalePrice.Text := TAccountComp.FormatMoney(0);
-end;
-
-procedure TWIZEnlistAccountForSale_Transaction.OnNext;
-begin
-  Model.SelectedIndex := cbSignerAccount.ItemIndex;
-  Model.SignerAccount := Model.SelectedAccounts[PtrInt(
-    cbSignerAccount.Items.Objects[cbSignerAccount.ItemIndex])];
-
-  UpdatePath(ptReplaceAllNext, [TWIZEnlistAccountForSale_TransactionPayload,
-    TWIZEnlistAccountForSale_Confirmation]);
-end;
-
-function TWIZEnlistAccountForSale_Transaction.Validate(out message: ansistring): boolean;
-var
-  c: cardinal;
-  i: integer;
-begin
-  Result := True;
-  if cbSignerAccount.ItemIndex < 1 then
-  begin
-    message := 'A signer account must be selected';
-    Result := False;
-    Exit;
-  end;
-
-  if not TAccountComp.TxtToMoney(edtSalePrice.Text, Model.SalePrice) then
-  begin
-    message := 'Invalid price (' + edtSalePrice.Text + ')';
-    Result := False;
-    Exit;
-  end;
-
-  if not (TAccountComp.AccountTxtNumberToAccountNumber(edtSellerAccount.Text, c)) then
-  begin
-    message := 'Invalid seller account (' + edtSellerAccount.Text + ')';
-    Result := False;
-    Exit;
-  end;
-
-  if (c < 0) or (c >= TNode.Node.Bank.AccountsCount) then
-  begin
-    message := 'Invalid seller account (' +
-      TAccountComp.AccountNumberToAccountTxtNumber(c) + ')';
-    Result := False;
-    Exit;
-  end;
-
-  for i := Low(Model.SelectedAccounts) to High(Model.SelectedAccounts) do
-  begin
-    if (Model.SelectedAccounts[i].Account = c) then
-    begin
-      message := 'Seller account cannot be same account';
-      Result := False;
-      Exit;
-    end;
-  end;
-
-  Model.SellerAccount := TNode.Node.Operations.SafeBoxTransaction.account(c);
-
-  if not TAccountComp.TxtToMoney(Trim(edtOpFee.Text), Model.Fee.DefaultFee) then
-  begin
-    message := 'Invalid fee value "' + edtOpFee.Text + '"';
-    Result := False;
-    Exit;
-  end;
-
-end;
-
-end.

+ 0 - 98
src/gui/wizards/operations/UWIZEnlistAccountForSale_TransactionPayload.lfm

@@ -1,98 +0,0 @@
-object WIZEnlistAccountForSale_TransactionPayload: TWIZEnlistAccountForSale_TransactionPayload
-  Left = 0
-  Height = 253
-  Top = 0
-  Width = 429
-  ActiveControl = mmoPayload
-  Caption = 'Form1'
-  ClientHeight = 253
-  ClientWidth = 429
-  LCLVersion = '1.8.1.0'
-  Visible = False
-  object grpPayload: TGroupBox
-    Left = 8
-    Height = 244
-    Top = 2
-    Width = 416
-    Anchors = [akTop, akLeft, akRight, akBottom]
-    Caption = 'Enlist Account 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 = 176
-        Caption = 'Encrypted with old public key'
-        TabOrder = 1
-      end
-      object rbEncryptedWithEC: TRadioButton
-        Left = 3
-        Height = 19
-        Top = 24
-        Width = 181
-        Caption = 'Encrypted with new 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

+ 0 - 82
src/gui/wizards/operations/UWIZEnlistAccountForSale_TransactionPayload.pas

@@ -1,82 +0,0 @@
-unit UWIZEnlistAccountForSale_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, UWizard, UWIZEnlistAccountForSale;
-
-type
-
-  { TWIZEnlistAccountForSale_TransactionPayload }
-
-  TWIZEnlistAccountForSale_TransactionPayload =
-    class(TWizardForm<TWIZEnlistAccountForSaleModel>)
-    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}
-
-{ TWIZEnlistAccountForSale_TransactionPayload }
-
-procedure TWIZEnlistAccountForSale_TransactionPayload.OnNext;
-begin
-  Model.Payload := mmoPayload.Lines.Text;
-  if rbEncryptedWithOldEC.Checked then
-  begin
-    Model.PayloadEncryptionMode := akaEncryptWithOldEC;
-  end
-  else
-  if rbEncryptedWithEC.Checked then
-  begin
-    Model.PayloadEncryptionMode := akaEncryptWithEC;
-  end
-  else
-  if rbEncryptedWithPassword.Checked then
-  begin
-    Model.PayloadEncryptionMode := akaEncryptWithPassword;
-  end
-  else
-  if rbNotEncrypted.Checked then
-  begin
-    Model.PayloadEncryptionMode := akaNotEncrypt;
-  end;
-end;
-
-function TWIZEnlistAccountForSale_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.

+ 1 - 0
src/gui/wizards/operations/UWIZOperationFee_Custom.lfm

@@ -7,6 +7,7 @@ object WIZOperationFee_Custom: TWIZOperationFee_Custom
   Caption = 'WIZOperationFee_Custom'
   Caption = 'WIZOperationFee_Custom'
   ClientHeight = 253
   ClientHeight = 253
   ClientWidth = 429
   ClientWidth = 429
+  LCLVersion = '1.8.2.0'
   Visible = False
   Visible = False
   object gbTransactionFee: TGroupBox
   object gbTransactionFee: TGroupBox
     Left = 14
     Left = 14

+ 26 - 6
src/gui/wizards/operations/UWIZOperationFee_Custom.pas

@@ -38,6 +38,7 @@ type
 
 
 
 
 
 
+
   public
   public
     procedure OnPresent; override;
     procedure OnPresent; override;
     procedure OnNext; override;
     procedure OnNext; override;
@@ -75,8 +76,8 @@ end;
 
 
 procedure TWIZOperationFee_Custom.OnNext;
 procedure TWIZOperationFee_Custom.OnNext;
 begin
 begin
-  TAccountComp.TxtToMoney(Trim(fseFee.ValueToStr(fseFee.Value)),
-    Model.Fee.SingleOperationFee);
+  //TAccountComp.TxtToMoney(Trim(fseFee.ValueToStr(fseFee.Value)),
+  //  Model.Fee.SingleOperationFee);
   if Model.Payload.HasPayload then
   if Model.Payload.HasPayload then
     UpdatePath(ptInject, [TWIZOperationPayload_Encryption])
     UpdatePath(ptInject, [TWIZOperationPayload_Encryption])
   else if Length(Model.Account.SelectedAccounts) > 1 then
   else if Length(Model.Account.SelectedAccounts) > 1 then
@@ -91,6 +92,8 @@ end;
 function TWIZOperationFee_Custom.Validate(out message: ansistring): boolean;
 function TWIZOperationFee_Custom.Validate(out message: ansistring): boolean;
 var
 var
   opfee: int64;
   opfee: int64;
+  i: integer;
+  acc: TAccount;
 begin
 begin
   Result := True;
   Result := True;
 
 
@@ -101,11 +104,28 @@ begin
     Exit;
     Exit;
   end;
   end;
 
 
-  if (opfee = 0) and (Length(Model.Account.SelectedAccounts) > 1) then
+  Model.Fee.SingleOperationFee := opfee;
+
+   if Length(Model.Account.SelectedAccounts) > 1 then
   begin
   begin
-    message := 'zero fee only allowed for single operations.';
-    Result := False;
-    Exit;
+    if not (Model.Fee.SingleOperationFee > 0) then
+    begin
+      message := 'zero fee only allowed for single operations.';
+      Result := False;
+      Exit;
+    end;
+  end;
+
+
+  for i := Low(Model.Account.SelectedAccounts) to High(Model.Account.SelectedAccounts) do
+  begin
+    acc := Model.Account.SelectedAccounts[i];
+    if acc.balance < Model.Fee.SingleOperationFee then
+    begin
+      message := 'Insufficient funds for fees in one or more accounts';
+      Result := False;
+      Exit;
+    end;
   end;
   end;
 end;
 end;
 
 

+ 0 - 36
src/gui/wizards/operations/UWIZOperationPayload_Encryption.lrs

@@ -1,36 +0,0 @@
-{ This is an automatically generated lazarus resource file }
-
-LazarusResources.Add('TWIZPayloadOverride','FORMDATA',[
-  'TPF0'#19'TWIZPayloadOverride'#18'WIZPayloadOverride'#4'Left'#2#0#6'Height'#3
-  +#253#0#3'Top'#2#0#5'Width'#3#173#1#13'ActiveControl'#7#21'rbEncryptedWithSen'
-  +'der'#7'Caption'#6#5'Form1'#12'ClientHeight'#3#253#0#11'ClientWidth'#3#173#1
-  +#10'LCLVersion'#6#7'1.8.2.0'#7'Visible'#8#0#9'TGroupBox'#10'grpPayload'#4'Le'
-  +'ft'#2#8#6'Height'#3#244#0#3'Top'#2#2#5'Width'#3#160#1#7'Anchors'#11#5'akTop'
-  +#6'akLeft'#7'akRight'#8'akBottom'#0#7'Caption'#6#19'Transaction Payload'#12
-  +'ClientHeight'#3#224#0#11'ClientWidth'#3#156#1#8'TabOrder'#2#0#0#6'TPanel'#9
-  +'paPayload'#4'Left'#2#8#6'Height'#3#214#0#3'Top'#2#2#5'Width'#3#140#1#7'Anch'
-  +'ors'#11#5'akTop'#6'akLeft'#7'akRight'#8'akBottom'#0#10'BevelOuter'#7#6'bvNo'
-  +'ne'#12'ClientHeight'#3#214#0#11'ClientWidth'#3#140#1#8'TabOrder'#2#0#0#12'T'
-  +'RadioButton'#24'rbEncryptedWithRecipient'#4'Left'#2#3#6'Height'#2#19#3'Top'
-  +#2'@'#5'Width'#3#156#0#7'Caption'#6#26'Encrypt with recipient key'#8'TabOrde'
-  +'r'#2#0#0#0#12'TRadioButton'#21'rbEncryptedWithSender'#4'Left'#2#3#6'Height'
-  +#2#19#3'Top'#2'p'#5'Width'#3#145#0#7'Caption'#6#23'Encrypt with sender key'#7
-  +'Checked'#9#8'TabOrder'#2#1#7'TabStop'#9#0#0#12'TRadioButton'#23'rbEncrypted'
-  +'WithPassword'#4'Left'#2#3#6'Height'#2#19#3'Top'#3#176#0#5'Width'#3#139#0#7
-  +'Caption'#6#21'Encrypt with password'#8'TabOrder'#2#2#0#0#12'TRadioButton'#14
-  +'rbNotEncrypted'#4'Left'#2#3#6'Height'#2#19#3'Top'#2#24#5'Width'#2'`'#7'Capt'
-  +'ion'#6#13'No Encryption'#8'TabOrder'#2#3#0#0#6'TLabel'#8'lblNote1'#4'Left'#2
-  +#3#6'Height'#2#15#3'Top'#2#3#5'Width'#3'W'#1#7'Caption'#6'@What type of payl'
-  +'oad would you like to attach to your operation?'#11'ParentColor'#8#0#0#6'TL'
-  +'abel'#15'lblNoEncryption'#4'Left'#2#19#6'Height'#2#15#3'Top'#2'.'#5'Width'#3
-  +'n'#1#7'Caption'#6'FUse this option to specify a publicly visible message an'
-  +'yone can view.'#11'ParentColor'#8#0#0#6'TLabel'#16'lblNoEncryption1'#4'Left'
-  +#2#19#6'Height'#2#15#3'Top'#2'X'#5'Width'#3'u'#1#7'Caption'#6'GUse this opti'
-  +'on to specify a message which only the recipient can view.'#11'ParentColor'
-  +#8#0#0#6'TLabel'#16'lblNoEncryption2'#4'Left'#2#19#6'Height'#2#30#3'Top'#3
-  +#136#0#5'Width'#3'y'#1#7'Caption'#6'~Only you will be able to decrypt this m'
-  +'essage. This is useful for tagging '#13#10'transactions for your own record'
-  +' keeping purposes.'#11'ParentColor'#8#0#0#6'TLabel'#6'Label1'#4'Left'#2#19#6
-  +'Height'#2#15#3'Top'#3#198#0#5'Width'#3'9'#1#7'Caption'#6';Only those with p'
-  +'assword will be able to view this message.'#11'ParentColor'#8#0#0#0#0#0
-]);

+ 1 - 0
src/gui/wizards/operations/UWIZSendPASC.pas

@@ -105,6 +105,7 @@ 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
 var
   c: cardinal;
   c: cardinal;
+  i: integer;
 begin
 begin
   Result := False;
   Result := False;
   errors := '';
   errors := '';

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

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

+ 0 - 15
src/gui/wizards/operations/UWIZSendPASC_Confirmation.pas

@@ -37,7 +37,6 @@ type
   public
   public
     procedure OnPresent; override;
     procedure OnPresent; override;
     procedure OnNext; override;
     procedure OnNext; override;
-    function Validate(out message: ansistring): boolean; override;
   end;
   end;
 
 
 
 
@@ -121,20 +120,6 @@ begin
   end;
   end;
 end;
 end;
 
 
-function TWIZSendPASC_Confirmation.Validate(out message: ansistring): boolean;
-begin
-  Result := True;
-  if Length(Model.Account.SelectedAccounts) > 1 then
-  begin
-    if not (Model.Fee.SingleOperationFee > 0) then
-    begin
-      message := 'insufficient fee for total operation.';
-      Result := False;
-      Exit;
-    end;
-  end;
-end;
-
 { TAccountSenderDataSource }
 { TAccountSenderDataSource }
 
 
 function TAccountSenderDataSource.GetColumns: TDataColumns;
 function TAccountSenderDataSource.GetColumns: TDataColumns;

+ 61 - 44
src/pascalcoin_wallet.lpi

@@ -33,7 +33,7 @@
         <PackageName Value="LCL"/>
         <PackageName Value="LCL"/>
       </Item1>
       </Item1>
     </RequiredPackages>
     </RequiredPackages>
-    <Units Count="98">
+    <Units Count="99">
       <Unit0>
       <Unit0>
         <Filename Value="pascalcoin_wallet.dpr"/>
         <Filename Value="pascalcoin_wallet.dpr"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
@@ -346,7 +346,7 @@
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
       </Unit62>
       </Unit62>
       <Unit63>
       <Unit63>
-        <Filename Value="core.utils\UCoreObjects.pas"/>
+        <Filename Value="core.utils\UCoreUtils.pas"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
       </Unit63>
       </Unit63>
       <Unit64>
       <Unit64>
@@ -410,149 +410,166 @@
       <Unit74>
       <Unit74>
         <Filename Value="gui\wizards\operations\UWIZEnlistAccountForSale_Confirmation.pas"/>
         <Filename Value="gui\wizards\operations\UWIZEnlistAccountForSale_Confirmation.pas"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
+        <ComponentName Value="WIZEnlistAccountForSale_Confirmation"/>
         <HasResources Value="True"/>
         <HasResources Value="True"/>
+        <ResourceBaseClass Value="Form"/>
       </Unit74>
       </Unit74>
       <Unit75>
       <Unit75>
-        <Filename Value="gui\wizards\operations\UWIZEnlistAccountForSale_List.pas"/>
+        <Filename Value="gui\wizards\operations\UWIZOperationFee_Custom.pas"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
+        <ComponentName Value="WIZOperationFee_Custom"/>
         <HasResources Value="True"/>
         <HasResources Value="True"/>
+        <ResourceBaseClass Value="Form"/>
       </Unit75>
       </Unit75>
       <Unit76>
       <Unit76>
-        <Filename Value="gui\wizards\operations\UWIZEnlistAccountForSale_PrivateSaleConfig.pas"/>
+        <Filename Value="gui\wizards\operations\UWIZOperationPayload_Content.pas"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
+        <ComponentName Value="WIZOperationPayload_Content"/>
         <HasResources Value="True"/>
         <HasResources Value="True"/>
+        <ResourceBaseClass Value="Form"/>
       </Unit76>
       </Unit76>
       <Unit77>
       <Unit77>
-        <Filename Value="gui\wizards\operations\UWIZEnlistAccountForSale_Start.pas"/>
+        <Filename Value="gui\wizards\operations\UWIZOperationPayload_Encryption.pas"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
+        <ComponentName Value="WIZOperationPayload_Encryption"/>
         <HasResources Value="True"/>
         <HasResources Value="True"/>
+        <ResourceBaseClass Value="Form"/>
       </Unit77>
       </Unit77>
       <Unit78>
       <Unit78>
-        <Filename Value="gui\wizards\operations\UWIZEnlistAccountForSale_Transaction.pas"/>
+        <Filename Value="gui\wizards\operations\UWIZOperationPayload_Password.pas"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZEnlistAccountForSale_Transaction"/>
+        <ComponentName Value="WIZOperationPayload_Password"/>
         <HasResources Value="True"/>
         <HasResources Value="True"/>
         <ResourceBaseClass Value="Form"/>
         <ResourceBaseClass Value="Form"/>
       </Unit78>
       </Unit78>
       <Unit79>
       <Unit79>
-        <Filename Value="gui\wizards\operations\UWIZEnlistAccountForSale_TransactionPayload.pas"/>
+        <Filename Value="gui\wizards\operations\UWIZOperationSigner_Select.pas"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
+        <ComponentName Value="WIZOperationSigner_Select"/>
         <HasResources Value="True"/>
         <HasResources Value="True"/>
+        <ResourceBaseClass Value="Form"/>
       </Unit79>
       </Unit79>
       <Unit80>
       <Unit80>
-        <Filename Value="gui\wizards\operations\UWIZOperationFee_Custom.pas"/>
+        <Filename Value="gui\wizards\operations\UWIZSendPASC.pas"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZOperationFee_Custom"/>
-        <HasResources Value="True"/>
-        <ResourceBaseClass Value="Form"/>
       </Unit80>
       </Unit80>
       <Unit81>
       <Unit81>
-        <Filename Value="gui\wizards\operations\UWIZOperationPayload_Content.pas"/>
+        <Filename Value="gui\wizards\operations\UWIZSendPASC_Confirmation.pas"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZOperationPayload_Content"/>
+        <ComponentName Value="WIZSendPASC_Confirmation"/>
         <HasResources Value="True"/>
         <HasResources Value="True"/>
         <ResourceBaseClass Value="Form"/>
         <ResourceBaseClass Value="Form"/>
       </Unit81>
       </Unit81>
       <Unit82>
       <Unit82>
-        <Filename Value="gui\wizards\operations\UWIZOperationPayload_Encryption.pas"/>
+        <Filename Value="gui\wizards\operations\UWIZSendPASC_ConfirmSender.pas"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZOperationPayload_Encryption"/>
+        <ComponentName Value="WIZSendPASC_ConfirmSender"/>
         <HasResources Value="True"/>
         <HasResources Value="True"/>
         <ResourceBaseClass Value="Form"/>
         <ResourceBaseClass Value="Form"/>
       </Unit82>
       </Unit82>
       <Unit83>
       <Unit83>
-        <Filename Value="gui\wizards\operations\UWIZOperationPayload_Password.pas"/>
+        <Filename Value="gui\wizards\operations\UWIZSendPASC_EnterQuantity.pas"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZOperationPayload_Password"/>
+        <ComponentName Value="WIZSendPASC_EnterQuantity"/>
         <HasResources Value="True"/>
         <HasResources Value="True"/>
         <ResourceBaseClass Value="Form"/>
         <ResourceBaseClass Value="Form"/>
       </Unit83>
       </Unit83>
       <Unit84>
       <Unit84>
-        <Filename Value="gui\wizards\operations\UWIZOperationSigner_Select.pas"/>
+        <Filename Value="gui\wizards\operations\UWIZSendPASC_EnterRecipient.pas"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZOperationSigner_Select"/>
+        <ComponentName Value="WIZSendPASC_EnterRecipient"/>
         <HasResources Value="True"/>
         <HasResources Value="True"/>
         <ResourceBaseClass Value="Form"/>
         <ResourceBaseClass Value="Form"/>
       </Unit84>
       </Unit84>
       <Unit85>
       <Unit85>
-        <Filename Value="gui\wizards\operations\UWIZSendPASC.pas"/>
+        <Filename Value="gui\wizards\operations\UWIZChangeKey.pas"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
       </Unit85>
       </Unit85>
       <Unit86>
       <Unit86>
-        <Filename Value="gui\wizards\operations\UWIZSendPASC_Confirmation.pas"/>
+        <Filename Value="gui\wizards\operations\UWIZChangeKey_SelectOption.pas"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZSendPASC_Confirmation"/>
+        <ComponentName Value="WIZChangeKey_SelectOption"/>
         <HasResources Value="True"/>
         <HasResources Value="True"/>
         <ResourceBaseClass Value="Form"/>
         <ResourceBaseClass Value="Form"/>
       </Unit86>
       </Unit86>
       <Unit87>
       <Unit87>
-        <Filename Value="gui\wizards\operations\UWIZSendPASC_ConfirmSender.pas"/>
+        <Filename Value="gui\wizards\operations\UWIZChangeKey_EnterKey.pas"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZSendPASC_ConfirmSender"/>
+        <ComponentName Value="WIZChangeKey_EnterKey"/>
         <HasResources Value="True"/>
         <HasResources Value="True"/>
         <ResourceBaseClass Value="Form"/>
         <ResourceBaseClass Value="Form"/>
       </Unit87>
       </Unit87>
       <Unit88>
       <Unit88>
-        <Filename Value="gui\wizards\operations\UWIZSendPASC_EnterQuantity.pas"/>
+        <Filename Value="gui\wizards\operations\UWIZChangeKey_SelectKey.pas"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZSendPASC_EnterQuantity"/>
+        <ComponentName Value="WIZChangeKey_SelectKey"/>
         <HasResources Value="True"/>
         <HasResources Value="True"/>
         <ResourceBaseClass Value="Form"/>
         <ResourceBaseClass Value="Form"/>
       </Unit88>
       </Unit88>
       <Unit89>
       <Unit89>
-        <Filename Value="gui\wizards\operations\UWIZSendPASC_EnterRecipient.pas"/>
+        <Filename Value="gui\wizards\operations\UWIZChangeKey_ConfirmAccount.pas"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZSendPASC_EnterRecipient"/>
+        <ComponentName Value="WIZChangeKey_ConfirmAccount"/>
         <HasResources Value="True"/>
         <HasResources Value="True"/>
         <ResourceBaseClass Value="Form"/>
         <ResourceBaseClass Value="Form"/>
       </Unit89>
       </Unit89>
       <Unit90>
       <Unit90>
-        <Filename Value="gui\wizards\operations\UWIZChangeKey.pas"/>
+        <Filename Value="gui\wizards\operations\UWIZChangeKey_Confirmation.pas"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
+        <ComponentName Value="WIZChangeKey_Confirmation"/>
+        <HasResources Value="True"/>
+        <ResourceBaseClass Value="Form"/>
       </Unit90>
       </Unit90>
       <Unit91>
       <Unit91>
-        <Filename Value="gui\wizards\operations\UWIZChangeKey_SelectOption.pas"/>
+        <Filename Value="gui-classic\UGridUtils.pas"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZChangeKey_SelectOption"/>
-        <HasResources Value="True"/>
-        <ResourceBaseClass Value="Form"/>
       </Unit91>
       </Unit91>
       <Unit92>
       <Unit92>
-        <Filename Value="gui\wizards\operations\UWIZChangeKey_EnterKey.pas"/>
+        <Filename Value="gui\wizards\operations\UWIZEnlistAccountForSale_EnterSeller.pas"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZChangeKey_EnterKey"/>
+        <ComponentName Value="WIZEnlistAccountForSale_EnterSeller"/>
         <HasResources Value="True"/>
         <HasResources Value="True"/>
         <ResourceBaseClass Value="Form"/>
         <ResourceBaseClass Value="Form"/>
       </Unit92>
       </Unit92>
       <Unit93>
       <Unit93>
-        <Filename Value="gui\wizards\operations\UWIZChangeKey_SelectKey.pas"/>
+        <Filename Value="gui\wizards\operations\UWIZEnlistAccountForSale_EnterSaleAmount.pas"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZChangeKey_SelectKey"/>
+        <ComponentName Value="WIZEnlistAccountForSale_EnterSaleAmount"/>
         <HasResources Value="True"/>
         <HasResources Value="True"/>
         <ResourceBaseClass Value="Form"/>
         <ResourceBaseClass Value="Form"/>
       </Unit93>
       </Unit93>
       <Unit94>
       <Unit94>
-        <Filename Value="gui\wizards\operations\UWIZChangeKey_ConfirmAccount.pas"/>
+        <Filename Value="gui\wizards\operations\UWIZEnlistAccountForSale_SelectOption.pas"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZChangeKey_ConfirmAccount"/>
+        <ComponentName Value="WIZEnlistAccountForSale_SelectOption"/>
         <HasResources Value="True"/>
         <HasResources Value="True"/>
         <ResourceBaseClass Value="Form"/>
         <ResourceBaseClass Value="Form"/>
       </Unit94>
       </Unit94>
       <Unit95>
       <Unit95>
-        <Filename Value="gui\wizards\operations\UWIZChangeKey_Confirmation.pas"/>
+        <Filename Value="gui\wizards\operations\UWIZEnlistAccountForSale_EnterLockingBlock.pas"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZChangeKey_Confirmation"/>
+        <ComponentName Value="WIZEnlistAccountForSale_EnterLockingBlock"/>
         <HasResources Value="True"/>
         <HasResources Value="True"/>
         <ResourceBaseClass Value="Form"/>
         <ResourceBaseClass Value="Form"/>
       </Unit95>
       </Unit95>
       <Unit96>
       <Unit96>
-        <Filename Value="gui-classic\UGridUtils.pas"/>
+        <Filename Value="gui\wizards\operations\UWIZEnlistAccountForSale_EnterPublicKey.pas"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
+        <ComponentName Value="WIZEnlistAccountForSale_EnterPublicKey"/>
+        <HasResources Value="True"/>
+        <ResourceBaseClass Value="Form"/>
       </Unit96>
       </Unit96>
       <Unit97>
       <Unit97>
-        <Filename Value="core.utils\UCoreUtils.pas"/>
+        <Filename Value="gui\wizards\operations\UWIZEnlistAccountForSale_ConfirmAccount.pas"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
+        <ComponentName Value="WIZEnlistAccountForSale_ConfirmAccount"/>
+        <HasResources Value="True"/>
+        <ResourceBaseClass Value="Form"/>
       </Unit97>
       </Unit97>
+      <Unit98>
+        <Filename Value="core.utils\UCoreObjects.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit98>
     </Units>
     </Units>
   </ProjectOptions>
   </ProjectOptions>
   <CompilerOptions>
   <CompilerOptions>