Browse Source

Finalize E-PASA implementation on JSON-RPC calls and document it

Pascal Coin 4 years ago
parent
commit
1e6c42355c
3 changed files with 113 additions and 57 deletions
  1. 9 9
      CHANGELOG.md
  2. 1 1
      src/core/UEPasaDecoder.pas
  3. 103 47
      src/core/URPC.pas

+ 9 - 9
CHANGELOG.md

@@ -13,16 +13,16 @@
   - Added "ABSTRACTMEM_USE_CACHE_ON_LISTS","ABSTRACTMEM_CACHE_MAX_ACCOUNTS","ABSTRACTMEM_CACHE_MAX_PUBKEYS" in order to customize cache values
   - Added "ABSTRACTMEM_USE_CACHE_ON_LISTS","ABSTRACTMEM_CACHE_MAX_ACCOUNTS","ABSTRACTMEM_CACHE_MAX_PUBKEYS" in order to customize cache values
 - Improved performance when downloading Safebox (Fresh installation)
 - Improved performance when downloading Safebox (Fresh installation)
 - JSON-RPC changes:  
 - JSON-RPC changes:  
-  - Updated "Operation Object" return values:
-    - "senders" : ARRAY
-      - "account_epasa" : (String) If operation was using valid E-PASA format and can be decoded, will return E-PASA format used
-    - "receivers" : ARRAY
-      - "account_epasa" : (String) If operation was using valid E-PASA format and can be decoded, will return E-PASA format used
-  - Updated "Multi Operation Object" return values:
-    - "senders" : ARRAY
-      - "account_epasa" : (String) If operation was using valid E-PASA format and can be decoded, will return E-PASA format used
-    - "receivers" : ARRAY
+  - Updated "Operation Object" and "Multi Operation Object" return values:
+    **(IF THE WALLET IS UNLOCKED Will automatically try to decrypt encoded payloads and also return E-PASA used)**
+    - "senders" or "receivers" : ARRAY
       - "account_epasa" : (String) If operation was using valid E-PASA format and can be decoded, will return E-PASA format used
       - "account_epasa" : (String) If operation was using valid E-PASA format and can be decoded, will return E-PASA format used
+      - "unenc_payload" : (String) If payload can be decoded returns unencoded value in readable format (no HEXASTRING)
+      - "unenc_hexpayload" : (HEXASTRING) Unencoded value in hexastring
+      - "payload_method" : (String) Can be "key" or "pwd"
+      - "enc_pubkey" : HexaString with public key (if "payload_method"="key")
+      - "pwd" : String with password used (if "payload_method"="pwd")
+  - Payload encoding will automatically set "payload_type" value based on encoding params in order to store E-PASA standard
   - Updated "findaccounts": 
   - Updated "findaccounts": 
     -New param "end" (integer, -1 for default): Will search from "start" to "end" (if "end"=-1 will search to the end)
     -New param "end" (integer, -1 for default): Will search from "start" to "end" (if "end"=-1 will search to the end)
   - New method "findblocks": Will search and return an array of "Block objects"
   - New method "findblocks": Will search and return an array of "Block objects"

+ 1 - 1
src/core/UEPasaDecoder.pas

@@ -147,7 +147,7 @@ begin
   if (AEPasa.PayloadType.HasTrait(ptAsciiFormatted)) then begin
   if (AEPasa.PayloadType.HasTrait(ptAsciiFormatted)) then begin
     AEPasa.Payload := LUnencryptedPayloadBytes.ToString;
     AEPasa.Payload := LUnencryptedPayloadBytes.ToString;
   end else if (AEPasa.PayloadType.HasTrait(ptHexFormatted)) then begin
   end else if (AEPasa.PayloadType.HasTrait(ptHexFormatted)) then begin
-    AEPasa.Payload := THexEncoding.Encode(LUnencryptedPayloadBytes,False);
+    AEPasa.Payload := THexEncoding.Encode(LUnencryptedPayloadBytes,True);
   end else if (AEPasa.PayloadType.HasTrait(ptBase58Formatted)) then begin
   end else if (AEPasa.PayloadType.HasTrait(ptBase58Formatted)) then begin
     AEPasa.Payload := TPascalBase58Encoding.Encode(LUnencryptedPayloadBytes);
     AEPasa.Payload := TPascalBase58Encoding.Encode(LUnencryptedPayloadBytes);
   end else begin
   end else begin

+ 103 - 47
src/core/URPC.pas

@@ -71,6 +71,7 @@ Type
     class procedure FillOperationsHashTreeObject(Const OperationsHashTree : TOperationsHashTree; jsonObject : TPCJSONObject);
     class procedure FillOperationsHashTreeObject(Const OperationsHashTree : TOperationsHashTree; jsonObject : TPCJSONObject);
     class procedure FillMultiOperationObject(current_protocol : Word; Const multiOperation : TOpMultiOperation; const ANode : TNode; const AWalletKeys : TWalletKeys; const APasswords : TList<String>; jsonObject : TPCJSONObject);
     class procedure FillMultiOperationObject(current_protocol : Word; Const multiOperation : TOpMultiOperation; const ANode : TNode; const AWalletKeys : TWalletKeys; const APasswords : TList<String>; jsonObject : TPCJSONObject);
     class procedure FillPublicKeyObject(const PubKey : TAccountKey; jsonObj : TPCJSONObject);
     class procedure FillPublicKeyObject(const PubKey : TAccountKey; jsonObj : TPCJSONObject);
+    class function FillEPasaOrDecrypt(const AAccount : Int64; Const APayload : TOperationPayload; const ANode : TNode; const AWalletKeys : TWalletKeys; const APasswords : TList<String>; jsonObject : TPCJSONObject) : Boolean;
     class function ToPascalCoins(jsonCurr : Real) : Int64;
     class function ToPascalCoins(jsonCurr : Real) : Int64;
     //
     //
     class Function HexaStringToOperationsHashTree(Const AHexaStringOperationsHashTree : String; ACurrentProtocol : Word; out AOperationsHashTree : TOperationsHashTree; var AErrors : String) : Boolean;
     class Function HexaStringToOperationsHashTree(Const AHexaStringOperationsHashTree : String; ACurrentProtocol : Word; out AOperationsHashTree : TOperationsHashTree; var AErrors : String) : Boolean;
@@ -217,6 +218,52 @@ begin
   end;
   end;
 end;
 end;
 
 
+class function TPascalCoinJSONComp.FillEPasaOrDecrypt(const AAccount: Int64;
+  const APayload: TOperationPayload; const ANode: TNode;
+  const AWalletKeys: TWalletKeys; const APasswords: TList<String>;
+  jsonObject: TPCJSONObject) : Boolean;
+var LEPasa : TEPasa;
+  i : Integer;
+  pkey : TECPrivateKey;
+  decrypted_payload : TRawBytes;
+  LDecodeEPasaResult : TDecodeEPasaResult;
+begin
+  Result := False;
+  if AAccount>=0 then begin
+    if TEPasaDecoder.TryDecodeEPASA(AAccount,APayload,ANode,AWalletKeys,APasswords,LDecodeEPasaResult,LEPasa) then begin
+      jsonObject.GetAsVariant('account_epasa').Value := LEPasa.ToClassicPASAString;
+      jsonObject.GetAsVariant('unenc_payload').Value := LEPasa.Payload;
+      jsonObject.GetAsVariant('unenc_hexpayload').Value := LEPasa.GetRawPayloadBytes.ToHexaString;
+      Result := True;
+    end;
+  end;
+  if (Not Result) and (Assigned(AWalletKeys)) and (LDecodeEPasaResult<>der_PrivateKeyNotFound) then begin
+    for i := 0 to AWalletKeys.Count - 1 do begin
+      pkey := AWalletKeys.Key[i].PrivateKey;
+      if (assigned(pkey)) then begin
+        if TPCEncryption.DoPascalCoinECIESDecrypt(pkey.PrivateKey,APayload.payload_raw,decrypted_payload) then begin
+          jsonObject.GetAsVariant('unenc_payload').Value:= decrypted_payload.ToPrintable;
+          jsonObject.GetAsVariant('unenc_hexpayload').Value:= TCrypto.ToHexaString(decrypted_payload);
+          jsonObject.GetAsVariant('payload_method').Value:= 'key';
+          jsonObject.GetAsVariant('enc_pubkey').Value:= TCrypto.ToHexaString(TAccountComp.AccountKey2RawString(pkey.PublicKey));
+          Result := true;
+        end;
+      end;
+    end;
+  end;
+  if (Not Result) And Assigned(APasswords) and (LDecodeEPasaResult<>der_PasswordNotFound) then begin
+    for i := 0 to APasswords.Count - 1 do begin
+      if TPCEncryption.DoPascalCoinAESDecrypt(APayload.payload_raw,TEncoding.ANSI.GetBytes(APasswords[i]),decrypted_payload) then begin
+        jsonObject.GetAsVariant('unenc_payload').Value:= decrypted_payload.ToPrintable;
+        jsonObject.GetAsVariant('unenc_hexpayload').Value:= TCrypto.ToHexaString(decrypted_payload);
+        jsonObject.GetAsVariant('payload_method').Value:= 'pwd';
+        jsonObject.GetAsVariant('pwd').Value:=APasswords[i];
+        Result := true;
+      end;
+    end;
+  end;
+end;
+
 class procedure TPascalCoinJSONComp.FillOperationObject(const OPR: TOperationResume; currentNodeBlocksCount : Cardinal;
 class procedure TPascalCoinJSONComp.FillOperationObject(const OPR: TOperationResume; currentNodeBlocksCount : Cardinal;
   const ANode : TNode; const AWalletKeys : TWalletKeys; const APasswords : TList<String>; jsonObject: TPCJSONObject);
   const ANode : TNode; const AWalletKeys : TWalletKeys; const APasswords : TList<String>; jsonObject: TPCJSONObject);
 Var i : Integer;
 Var i : Integer;
@@ -224,6 +271,7 @@ Var i : Integer;
   LString : String;
   LString : String;
   jsonArr : TPCJSONArray;
   jsonArr : TPCJSONArray;
   auxObj : TPCJSONObject;
   auxObj : TPCJSONObject;
+  LEPasa : TEPasa;
 
 
   procedure FillOpDataObject(AParentObj : TPCJSONObject; const AOpData : TMultiOpData);
   procedure FillOpDataObject(AParentObj : TPCJSONObject; const AOpData : TMultiOpData);
   var LDataObj : TPCJSONObject;
   var LDataObj : TPCJSONObject;
@@ -262,7 +310,7 @@ Begin
       LString := TCrypto.ToHexaString(OPR.Senders[i].Payload.payload_raw);
       LString := TCrypto.ToHexaString(OPR.Senders[i].Payload.payload_raw);
       auxObj := jsonArr.GetAsObject(jsonArr.Count);
       auxObj := jsonArr.GetAsObject(jsonArr.Count);
       auxObj.GetAsVariant('account').Value := OPR.Senders[i].Account;
       auxObj.GetAsVariant('account').Value := OPR.Senders[i].Account;
-      auxObj.GetAsVariant('account_epasa').Value := TEPasaDecoder.DecodeEPASA(OPR.Senders[i].Account,OPR.Senders[i].Payload,ANode,AWalletKeys,APasswords);
+      FillEPasaOrDecrypt(OPR.Senders[i].Account,OPR.Senders[i].Payload,ANode,AWalletKeys,APasswords,auxObj);
       if (OPR.Senders[i].N_Operation>0) then auxObj.GetAsVariant('n_operation').Value := OPR.Senders[i].N_Operation;
       if (OPR.Senders[i].N_Operation>0) then auxObj.GetAsVariant('n_operation').Value := OPR.Senders[i].N_Operation;
       auxObj.GetAsVariant('amount').Value := TAccountComp.FormatMoneyDecimal(OPR.Senders[i].Amount * (-1));
       auxObj.GetAsVariant('amount').Value := TAccountComp.FormatMoneyDecimal(OPR.Senders[i].Amount * (-1));
       auxObj.GetAsVariant('amount_s').Value := TAccountComp.FormatMoney (OPR.Senders[i].Amount * (-1));
       auxObj.GetAsVariant('amount_s').Value := TAccountComp.FormatMoney (OPR.Senders[i].Amount * (-1));
@@ -277,7 +325,7 @@ Begin
     for i:=Low(OPR.Receivers) to High(OPR.Receivers) do begin
     for i:=Low(OPR.Receivers) to High(OPR.Receivers) do begin
       auxObj := jsonArr.GetAsObject(jsonArr.Count);
       auxObj := jsonArr.GetAsObject(jsonArr.Count);
       auxObj.GetAsVariant('account').Value := OPR.Receivers[i].Account;
       auxObj.GetAsVariant('account').Value := OPR.Receivers[i].Account;
-      auxObj.GetAsVariant('account_epasa').Value := TEPasaDecoder.DecodeEPASA(OPR.Receivers[i].Account,OPR.Receivers[i].Payload,ANode,AWalletKeys,APasswords);
+      FillEPasaOrDecrypt(OPR.Receivers[i].Account,OPR.Receivers[i].Payload,ANode,AWalletKeys,APasswords,auxObj);
       auxObj.GetAsVariant('amount').Value :=  TAccountComp.FormatMoneyDecimal(OPR.Receivers[i].Amount);
       auxObj.GetAsVariant('amount').Value :=  TAccountComp.FormatMoneyDecimal(OPR.Receivers[i].Amount);
       auxObj.GetAsVariant('amount_s').Value :=  TAccountComp.FormatMoney(OPR.Receivers[i].Amount);
       auxObj.GetAsVariant('amount_s').Value :=  TAccountComp.FormatMoney(OPR.Receivers[i].Amount);
       auxObj.GetAsVariant('payload').Value := TCrypto.ToHexaString(OPR.Receivers[i].Payload.payload_raw);
       auxObj.GetAsVariant('payload').Value := TCrypto.ToHexaString(OPR.Receivers[i].Payload.payload_raw);
@@ -489,20 +537,39 @@ class function TPascalCoinJSONComp.CheckAndGetEncodedRAWPayload(
   out AOperationPayload : TOperationPayload;
   out AOperationPayload : TOperationPayload;
   var AErrorNum: Integer;
   var AErrorNum: Integer;
   var AErrorDesc: String): Boolean;
   var AErrorDesc: String): Boolean;
+var LNewPayloadType : TPayloadType;
 begin
 begin
   AOperationPayload := CT_TOperationPayload_NUL;
   AOperationPayload := CT_TOperationPayload_NUL;
   AOperationPayload.payload_type := APayloadType.ToProtocolValue;
   AOperationPayload.payload_type := APayloadType.ToProtocolValue;
   if (Length(ARawPayload)>0) then begin
   if (Length(ARawPayload)>0) then begin
+    if ARawPayload.ToPrintable.CompareTo(ARawPayload.ToString)=0 then LNewPayloadType := [ptAsciiFormatted]
+    else LNewPayloadType := [];
     if (APayload_method='none') then begin
     if (APayload_method='none') then begin
       AOperationPayload.payload_raw:=ARawPayload;
       AOperationPayload.payload_raw:=ARawPayload;
+      if (AOperationPayload.payload_type=0) then begin
+        LNewPayloadType := LNewPayloadType + [ptPublic];
+        AOperationPayload.payload_type := LNewPayloadType.ToProtocolValue;
+      end;
       Result := True;
       Result := True;
     end else if (APayload_method='dest') then begin
     end else if (APayload_method='dest') then begin
       Result := TPCEncryption.DoPascalCoinECIESEncrypt(ATargetAccountKey,ARawPayload,AOperationPayload.payload_raw);
       Result := TPCEncryption.DoPascalCoinECIESEncrypt(ATargetAccountKey,ARawPayload,AOperationPayload.payload_raw);
+      if (AOperationPayload.payload_type=0) then begin
+        LNewPayloadType := LNewPayloadType + [ptRecipientKeyEncrypted];
+        AOperationPayload.payload_type := LNewPayloadType.ToProtocolValue;
+      end;
     end else if (APayload_method='sender') then begin
     end else if (APayload_method='sender') then begin
       Result := TPCEncryption.DoPascalCoinECIESEncrypt(ASenderAccounKey,ARawPayload,AOperationPayload.payload_raw);
       Result := TPCEncryption.DoPascalCoinECIESEncrypt(ASenderAccounKey,ARawPayload,AOperationPayload.payload_raw);
+      if (AOperationPayload.payload_type=0) then begin
+        LNewPayloadType := LNewPayloadType + [ptSenderKeyEncrypted];
+        AOperationPayload.payload_type := LNewPayloadType.ToProtocolValue;
+      end;
     end else if (APayload_method='aes') then begin
     end else if (APayload_method='aes') then begin
       AOperationPayload.payload_raw := TPCEncryption.DoPascalCoinAESEncrypt(ARawPayload,TEncoding.ANSI.GetBytes(AEncodePwdForAES));
       AOperationPayload.payload_raw := TPCEncryption.DoPascalCoinAESEncrypt(ARawPayload,TEncoding.ANSI.GetBytes(AEncodePwdForAES));
       Result := True;
       Result := True;
+      if (AOperationPayload.payload_type=0) then begin
+        LNewPayloadType := LNewPayloadType + [ptPasswordEncrypted];
+        AOperationPayload.payload_type := LNewPayloadType.ToProtocolValue;
+      end;
     end else begin
     end else begin
       Result := False;
       Result := False;
       AErrorNum:=CT_RPC_ErrNum_InvalidOperation;
       AErrorNum:=CT_RPC_ErrNum_InvalidOperation;
@@ -599,7 +666,7 @@ begin
     LStr := TCrypto.ToHexaString(multiOperation.Data.txSenders[i].Payload.payload_raw);
     LStr := TCrypto.ToHexaString(multiOperation.Data.txSenders[i].Payload.payload_raw);
     auxObj := jsonArr.GetAsObject(jsonArr.Count);
     auxObj := jsonArr.GetAsObject(jsonArr.Count);
     auxObj.GetAsVariant('account').Value := multiOperation.Data.txSenders[i].Account;
     auxObj.GetAsVariant('account').Value := multiOperation.Data.txSenders[i].Account;
-    auxObj.GetAsVariant('account_epasa').Value := TEPasaDecoder.DecodeEPASA(multiOperation.Data.txSenders[i].Account,multiOperation.Data.txSenders[i].Payload,ANode,AWalletKeys,APasswords);
+    FillEPasaOrDecrypt(multiOperation.Data.txSenders[i].Account,multiOperation.Data.txSenders[i].Payload,ANode,AWalletKeys,APasswords,auxObj);
     auxObj.GetAsVariant('n_operation').Value := multiOperation.Data.txSenders[i].N_Operation;
     auxObj.GetAsVariant('n_operation').Value := multiOperation.Data.txSenders[i].N_Operation;
     auxObj.GetAsVariant('amount').Value := TAccountComp.FormatMoneyDecimal(multiOperation.Data.txSenders[i].Amount * (-1));
     auxObj.GetAsVariant('amount').Value := TAccountComp.FormatMoneyDecimal(multiOperation.Data.txSenders[i].Amount * (-1));
     auxObj.GetAsVariant('payload').Value := LStr;
     auxObj.GetAsVariant('payload').Value := LStr;
@@ -611,7 +678,7 @@ begin
     LStr := TCrypto.ToHexaString(multiOperation.Data.txSenders[i].Payload.payload_raw);
     LStr := TCrypto.ToHexaString(multiOperation.Data.txSenders[i].Payload.payload_raw);
     auxObj := jsonArr.GetAsObject(jsonArr.Count);
     auxObj := jsonArr.GetAsObject(jsonArr.Count);
     auxObj.GetAsVariant('account').Value := multiOperation.Data.txReceivers[i].Account;
     auxObj.GetAsVariant('account').Value := multiOperation.Data.txReceivers[i].Account;
-    auxObj.GetAsVariant('account_epasa').Value := TEPasaDecoder.DecodeEPASA(multiOperation.Data.txReceivers[i].Account,multiOperation.Data.txReceivers[i].Payload,ANode,AWalletKeys,APasswords);
+    FillEPasaOrDecrypt(multiOperation.Data.txReceivers[i].Account,multiOperation.Data.txReceivers[i].Payload,ANode,AWalletKeys,APasswords,auxObj);
     auxObj.GetAsVariant('amount').Value := TAccountComp.FormatMoneyDecimal(multiOperation.Data.txReceivers[i].Amount);
     auxObj.GetAsVariant('amount').Value := TAccountComp.FormatMoneyDecimal(multiOperation.Data.txReceivers[i].Amount);
     auxObj.GetAsVariant('payload').Value := TCrypto.ToHexaString(multiOperation.Data.txReceivers[i].Payload.payload_raw);
     auxObj.GetAsVariant('payload').Value := TCrypto.ToHexaString(multiOperation.Data.txReceivers[i].Payload.payload_raw);
     auxObj.GetAsVariant('payload_type').Value := multiOperation.Data.txReceivers[i].Payload.payload_type;
     auxObj.GetAsVariant('payload_type').Value := multiOperation.Data.txReceivers[i].Payload.payload_type;
@@ -1687,48 +1754,44 @@ function TRPCProcess.ProcessMethod(const method: String; params: TPCJSONObject;
     Result := true;
     Result := true;
   end;
   end;
 
 
-  Function DoDecrypt(RawEncryptedPayload : TRawBytes; jsonArrayPwds : TPCJSONArray) : Boolean;
+  Function DoDecrypt(jsonArrayPwds : TPCJSONArray) : Boolean;
   var i : Integer;
   var i : Integer;
     pkey : TECPrivateKey;
     pkey : TECPrivateKey;
     decrypted_payload : TRawBytes;
     decrypted_payload : TRawBytes;
+    LPayload : TOperationPayload;
+    s : String;
+    Lpasswords : TList<String>;
   Begin
   Begin
-    Result := false;
-    if Length(RawEncryptedPayload)=0 then begin
-      GetResultObject.GetAsVariant('result').Value:= False;
-      GetResultObject.GetAsVariant('enc_payload').Value:= '';
-      Result := true;
-      exit;
+    if Length(params.AsString('payload',''))=0 then begin
+      ErrorNum:= CT_RPC_ErrNum_InvalidData;
+      ErrorDesc := 'Need param "payload"';
+      Exit(False);
     end;
     end;
-    for i := 0 to _RPCServer.WalletKeys.Count - 1 do begin
-      pkey := _RPCServer.WalletKeys.Key[i].PrivateKey;
-      if (assigned(pkey)) then begin
-        if TPCEncryption.DoPascalCoinECIESDecrypt(pkey.PrivateKey,RawEncryptedPayload,decrypted_payload) then begin
-          GetResultObject.GetAsVariant('result').Value:= true;
-          GetResultObject.GetAsVariant('enc_payload').Value:= TCrypto.ToHexaString(RawEncryptedPayload);
-          GetResultObject.GetAsVariant('unenc_payload').Value:= decrypted_payload.ToPrintable;
-          GetResultObject.GetAsVariant('unenc_hexpayload').Value:= TCrypto.ToHexaString(decrypted_payload);
-          GetResultObject.GetAsVariant('payload_method').Value:= 'key';
-          GetResultObject.GetAsVariant('enc_pubkey').Value:= TCrypto.ToHexaString(TAccountComp.AccountKey2RawString(pkey.PublicKey));
-          Result := true;
-          Exit;
-        end;
-      end;
+    LPayload.payload_raw := TCrypto.HexaToRaw(params.AsString('payload',''));
+    LPayload.payload_type := params.AsInteger('payload_type',0);
+    if Length(LPayload.payload_raw)=0 then begin
+      ErrorNum:= CT_RPC_ErrNum_InvalidData;
+      ErrorDesc := '"payload" param is not an HEXASTRING';
+      Exit(False);
     end;
     end;
-    for i := 0 to jsonArrayPwds.Count - 1 do begin
-      if TPCEncryption.DoPascalCoinAESDecrypt(RawEncryptedPayload,TEncoding.ANSI.GetBytes(jsonArrayPwds.GetAsVariant(i).AsString('')),decrypted_payload) then begin
-        GetResultObject.GetAsVariant('result').Value:= true;
-        GetResultObject.GetAsVariant('enc_payload').Value:= TCrypto.ToHexaString(RawEncryptedPayload);
-        GetResultObject.GetAsVariant('unenc_payload').Value:= decrypted_payload.ToPrintable;
-        GetResultObject.GetAsVariant('unenc_hexpayload').Value:= TCrypto.ToHexaString(decrypted_payload);
-        GetResultObject.GetAsVariant('payload_method').Value:= 'pwd';
-        GetResultObject.GetAsVariant('pwd').Value:= jsonArrayPwds.GetAsVariant(i).AsString('');
-        Result := true;
-        exit;
+    Lpasswords := TList<String>.Create;
+    Try
+      for i := 0 to jsonArrayPwds.Count-1 do begin
+        s := jsonArrayPwds.GetAsVariant(i).AsString('');
+        if Lpasswords.IndexOf(s)<0 then Lpasswords.Add(s);
       end;
       end;
-    end;
-    // Not found
-    GetResultObject.GetAsVariant('result').Value:= False;
-    GetResultObject.GetAsVariant('enc_payload').Value:= TCrypto.ToHexaString(RawEncryptedPayload);
+
+      if TPascalCoinJSONComp.FillEPasaOrDecrypt(-1,LPayload,FNode,FRPCServer.WalletKeys,Lpasswords,GetResultObject) then begin
+        GetResultObject.GetAsVariant('result').Value:= True;
+      end else begin
+        GetResultObject.GetAsVariant('result').Value:= False;
+      end;
+      GetResultObject.GetAsVariant('enc_payload').Value:= TCrypto.ToHexaString(LPayload.payload_raw);
+
+    Finally
+      Lpasswords.Free;
+    End;
+
     Result := true;
     Result := true;
   End;
   End;
 
 
@@ -3653,19 +3716,12 @@ begin
       ErrorNum := CT_RPC_ErrNum_NotAllowedCall;
       ErrorNum := CT_RPC_ErrNum_NotAllowedCall;
       Exit;
       Exit;
     end;
     end;
-    // Decrypts a "payload" searching for wallet private keys and for array of strings in "pwds" param
-    // Returns an JSON Object with "result" (Boolean) and
-    if (params.AsString('payload','')='') then begin
-      ErrorNum:= CT_RPC_ErrNum_InvalidData;
-      ErrorDesc := 'Need param "payload"';
-      exit;
-    end;
     If Not _RPCServer.WalletKeys.IsValidPassword then begin
     If Not _RPCServer.WalletKeys.IsValidPassword then begin
       ErrorNum := CT_RPC_ErrNum_WalletPasswordProtected;
       ErrorNum := CT_RPC_ErrNum_WalletPasswordProtected;
       ErrorDesc := 'Wallet is password protected. Unlock first';
       ErrorDesc := 'Wallet is password protected. Unlock first';
       exit;
       exit;
     end;
     end;
-    Result := DoDecrypt(TCrypto.HexaToRaw(params.AsString('payload','')),params.GetAsArray('pwds'));
+    Result := DoDecrypt(params.GetAsArray('pwds'));
   end else if (method='getconnections') then begin
   end else if (method='getconnections') then begin
     if (Not _RPCServer.AllowUsePrivateKeys) then begin
     if (Not _RPCServer.AllowUsePrivateKeys) then begin
       // Protection when server is locked to avoid private keys call
       // Protection when server is locked to avoid private keys call