From dc66da10ec9e1bfbcf765da6ace57977d09e6b96 Mon Sep 17 00:00:00 2001 From: Afshin Arani Date: Thu, 12 Oct 2023 12:53:13 +0330 Subject: [PATCH 1/3] Backend/Ether: rm etcIsMomentarilyCentralized flag ETC was previously marked as non-centeralized[1], this commit removes this flag since it's no longer needed. [1] 9392215bfa6c0f625ddce6423b3bf77a0dea8558 --- src/GWallet.Backend/Ether/EtherServer.fs | 34 +++++------------------- 1 file changed, 7 insertions(+), 27 deletions(-) diff --git a/src/GWallet.Backend/Ether/EtherServer.fs b/src/GWallet.Backend/Ether/EtherServer.fs index e755a1bb3..1bb2dcfbf 100644 --- a/src/GWallet.Backend/Ether/EtherServer.fs +++ b/src/GWallet.Backend/Ether/EtherServer.fs @@ -340,11 +340,9 @@ module Server = | ServerSelectionMode.Fast -> 3u | ServerSelectionMode.Analysis -> 2u - let etcEcosystemIsMomentarilyCentralized = false - let private FaultTolerantParallelClientInnerSettings (numberOfConsistentResponsesRequired: uint32) (mode: ServerSelectionMode) - currency + _currency maybeConsistencyConfig = let consistencyConfig = @@ -352,10 +350,7 @@ module Server = | None -> SpecificNumberOfConsistentResponsesRequired numberOfConsistentResponsesRequired | Some specificConsistencyConfig -> specificConsistencyConfig - let retries = - match currency with - | Currency.ETC when etcEcosystemIsMomentarilyCentralized -> Config.NUMBER_OF_RETRIES_TO_SAME_SERVERS * 2u - | _ -> Config.NUMBER_OF_RETRIES_TO_SAME_SERVERS + let retries = Config.NUMBER_OF_RETRIES_TO_SAME_SERVERS { NumberOfParallelJobsAllowed = NumberOfParallelJobsForMode mode @@ -377,11 +372,7 @@ module Server = } let private FaultTolerantParallelClientDefaultSettings (mode: ServerSelectionMode) (currency: Currency) = - let numberOfConsistentResponsesRequired = - if etcEcosystemIsMomentarilyCentralized && currency = Currency.ETC then - 1u - else - 2u + let numberOfConsistentResponsesRequired = 2u FaultTolerantParallelClientInnerSettings numberOfConsistentResponsesRequired mode currency @@ -390,9 +381,7 @@ module Server = (currency: Currency) (cacheOrInitialBalanceMatchFunc: decimal->bool) = let consistencyConfig = - if etcEcosystemIsMomentarilyCentralized && currency = Currency.ETC then - None - elif mode = ServerSelectionMode.Fast then + if mode = ServerSelectionMode.Fast then Some (OneServerConsistentWithCertainValueOrTwoServers cacheOrInitialBalanceMatchFunc) else None @@ -407,7 +396,7 @@ module Server = let Web3ServerToRetrievalFunc (server: ServerDetails) (web3ClientFunc: SomeWeb3->Async<'R>) - currency + _currency : Async<'R> = let HandlePossibleEtherFailures (job: Async<'R>): Async<'R> = @@ -422,12 +411,7 @@ module Server = return raise <| FSharpUtil.ReRaise ex } - let connectionTimeout = - match currency with - | Currency.ETC when etcEcosystemIsMomentarilyCentralized -> - Config.DEFAULT_NETWORK_TIMEOUT + Config.DEFAULT_NETWORK_TIMEOUT - | _ -> - Config.DEFAULT_NETWORK_TIMEOUT + let connectionTimeout = Config.DEFAULT_NETWORK_TIMEOUT async { let web3Server = Web3Server (connectionTimeout, server) @@ -678,11 +662,7 @@ module Server = return hexBigInteger } GetRandomizedFuncs currency web3Func - let minResponsesRequired = - if etcEcosystemIsMomentarilyCentralized && currency = Currency.ETC then - 1u - else - 2u + let minResponsesRequired = 2u return! faultTolerantEtherClient.Query (FaultTolerantParallelClientDefaultSettings ServerSelectionMode.Fast From 10b5fd98d074e705353e99badfe9bdb01a4ba15c Mon Sep 17 00:00:00 2001 From: Afshin Arani Date: Tue, 3 Oct 2023 17:02:29 +0330 Subject: [PATCH 2/3] Backend: update Nethereum to latest version This commit updates Nethereum to latest version to support extracting token transfer amount from the raw tx created when sending (hot-storage) or signing (cold-storage). It's noteworthy to say that Web3 no longer accepts a timeout as an argument. Nethereum now supports different types of transactions like those that support EIP-1559, at this moment there's no clear benefit for migrating especially given the fact that it will causes incompatiblity with ETC so we will continue to use Legacy types for now. --- .../GWallet.Backend.Tests-legacy.fsproj | 12 +- src/GWallet.Backend.Tests/packages.config | 5 +- src/GWallet.Backend/Ether/EtherAccount.fs | 18 +-- src/GWallet.Backend/Ether/EtherServer.fs | 25 +++-- src/GWallet.Backend/Ether/TokenManager.fs | 2 +- .../GWallet.Backend-legacy.fsproj | 46 ++++++-- src/GWallet.Backend/GWallet.Backend.fsproj | 5 +- src/GWallet.Backend/packages.config | 5 +- src/GWallet.Frontend.Console/App.config | 12 ++ .../GWallet.Frontend.XF.Android.fsproj | 98 +++++++++++------ .../packages.config | 5 +- .../GWallet.Frontend.XF.Gtk.fsproj | 103 ++++++++++++------ src/GWallet.Frontend.XF.Gtk/packages.config | 5 +- .../GWallet.Frontend.XF.Mac.fsproj | 103 ++++++++++++------ src/GWallet.Frontend.XF.Mac/packages.config | 5 +- .../GWallet.Frontend.XF.iOS.fsproj | 103 ++++++++++++------ src/GWallet.Frontend.XF.iOS/packages.config | 5 +- 17 files changed, 366 insertions(+), 191 deletions(-) diff --git a/src/GWallet.Backend.Tests/GWallet.Backend.Tests-legacy.fsproj b/src/GWallet.Backend.Tests/GWallet.Backend.Tests-legacy.fsproj index 7657a1ea9..ffa447184 100644 --- a/src/GWallet.Backend.Tests/GWallet.Backend.Tests-legacy.fsproj +++ b/src/GWallet.Backend.Tests/GWallet.Backend.Tests-legacy.fsproj @@ -131,7 +131,7 @@ ..\..\packages\NBitcoin.Altcoins.3.0.8\lib\net452\NBitcoin.Altcoins.dll - ..\..\packages\Microsoft.Extensions.Logging.Abstractions.1.0.2\lib\netstandard1.1\Microsoft.Extensions.Logging.Abstractions.dll + ..\..\packages\Microsoft.Extensions.Logging.Abstractions.6.0.0\lib\net461\Microsoft.Extensions.Logging.Abstractions.dll ..\..\packages\NBitcoin.6.0.17\lib\net461\NBitcoin.dll @@ -153,10 +153,20 @@ ..\..\packages\System.Runtime.Extensions.4.3.0\lib\net462\System.Runtime.Extensions.dll + + ..\..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + ..\..\packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + + + ..\..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll + + diff --git a/src/GWallet.Backend.Tests/packages.config b/src/GWallet.Backend.Tests/packages.config index db38c0fe3..fc6c7a1f5 100644 --- a/src/GWallet.Backend.Tests/packages.config +++ b/src/GWallet.Backend.Tests/packages.config @@ -2,7 +2,7 @@ - + @@ -15,10 +15,13 @@ + + + diff --git a/src/GWallet.Backend/Ether/EtherAccount.fs b/src/GWallet.Backend/Ether/EtherAccount.fs index ec4fe860c..b9b26e355 100644 --- a/src/GWallet.Backend/Ether/EtherAccount.fs +++ b/src/GWallet.Backend/Ether/EtherAccount.fs @@ -8,6 +8,7 @@ open System.Numerics open System.Threading.Tasks open Nethereum.ABI.Decoders +open Nethereum.Model open Nethereum.Signer open Nethereum.KeyStore open Nethereum.Util @@ -20,7 +21,7 @@ open GWallet.Backend.FSharpUtil.UwpHacks module internal Account = let private addressUtil = AddressUtil() - let private signer = TransactionSigner() + let private signer = LegacyTransactionSigner() let private KeyStoreService = KeyStoreService() @@ -236,7 +237,7 @@ module internal Account = let private ValidateMinerFee (trans: string) = let intDecoder = IntTypeDecoder() - let tx = TransactionFactory.CreateTransaction trans + let tx = TransactionFactory.CreateTransaction trans :?> SignedLegacyTransaction let amountInWei = intDecoder.DecodeBigInteger tx.Value @@ -365,8 +366,7 @@ module internal Account = else failwith <| SPrintF1 "Assertion failed: Ether currency %A not supported?" account.Currency - let chain = GetNetwork account.Currency - if not (signer.VerifyTransaction(trans, chain)) then + if not (TransactionVerificationAndRecovery.VerifyTransaction trans) then failwith "Transaction could not be verified?" trans @@ -461,7 +461,7 @@ module internal Account = signedTransaction.TransactionInfo.Proposal :> ITransactionDetails | _ -> - let getTransactionChainId (tx: TransactionBase) = + let getTransactionChainId (tx: SignedLegacyTransactionBase) = // the chain id can be deconstructed like so - // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md // into one of the following - @@ -472,22 +472,22 @@ module internal Account = let chainId = (v - BigInteger 35) / BigInteger 2 chainId - let getTransactionCurrency (tx: TransactionBase) = + let getTransactionCurrency (tx: SignedLegacyTransactionBase) = match int (getTransactionChainId tx) with | chainId when chainId = int Config.EthNet -> ETH | chainId when chainId = int Config.EtcNet -> ETC | other -> failwith <| SPrintF1 "Could not infer currency from transaction where chainId = %i." other - let tx = TransactionFactory.CreateTransaction signedTransaction.RawTransaction + let tx = TransactionFactory.CreateTransaction signedTransaction.RawTransaction :?> SignedLegacyTransaction // HACK: I prefix 12 elements to the address due to AddressTypeDecoder expecting some sort of header... let address = AddressTypeDecoder().Decode (Array.append (Array.zeroCreate 12) tx.ReceiveAddress) - let destAddress = addressUtil.ConvertToChecksumAddress address + let destAddress = address.ConvertToEthereumChecksumAddress() let txDetails = { - OriginAddress = signer.GetSenderAddress signedTransaction.RawTransaction + OriginAddress = TransactionVerificationAndRecovery.GetSenderAddress signedTransaction.RawTransaction Amount = UnitConversion.Convert.FromWei (IntTypeDecoder().DecodeBigInteger tx.Value) Currency = getTransactionCurrency tx DestinationAddress = destAddress diff --git a/src/GWallet.Backend/Ether/EtherServer.fs b/src/GWallet.Backend/Ether/EtherServer.fs index 1bb2dcfbf..b80fcda66 100644 --- a/src/GWallet.Backend/Ether/EtherServer.fs +++ b/src/GWallet.Backend/Ether/EtherServer.fs @@ -8,6 +8,7 @@ open System.Linq open Nethereum.Util open Nethereum.Hex.HexTypes +open Nethereum.JsonRpc.Client open Nethereum.Web3 open Nethereum.RPC.Eth.DTOs open Nethereum.StandardTokenEIP20.ContractDefinition @@ -20,8 +21,8 @@ type BalanceType = | Unconfirmed | Confirmed -type SomeWeb3 (connectionTimeOut, url: string) = - inherit Web3 (connectionTimeOut, url) +type SomeWeb3 (url: string) = + inherit Web3 (url) member val Url = url with get @@ -67,7 +68,7 @@ module Web3ServerSeedList = module Server = - let private Web3Server (connectionTimeOut, serverDetails: ServerDetails) = + let private Web3Server (serverDetails: ServerDetails) = match serverDetails.ServerInfo.ConnectionType with | { Protocol = Tcp _ ; Encrypted = _ } -> failwith <| SPrintF1 "Ether server of TCP connection type?: %s" serverDetails.ServerInfo.NetworkPath @@ -78,7 +79,7 @@ module Server = else "http" let uri = SPrintF2 "%s://%s" protocol serverDetails.ServerInfo.NetworkPath - SomeWeb3 (connectionTimeOut, uri) + SomeWeb3 uri let HttpRequestExceptionMatchesErrorCode (ex: Http.HttpRequestException) (errorCode: int): bool = ex.Message.StartsWith(SPrintF1 "%i " errorCode) || ex.Message.Contains(SPrintF1 " %i " errorCode) @@ -200,7 +201,7 @@ module Server = ] let MaybeRethrowRpcResponseException (ex: Exception): unit = - let maybeRpcResponseEx = FSharpUtil.FindException ex + let maybeRpcResponseEx = FSharpUtil.FindException ex match maybeRpcResponseEx with | Some rpcResponseEx -> if not (isNull rpcResponseEx.RpcError) then @@ -243,7 +244,7 @@ module Server = let MaybeRethrowRpcClientTimeoutException (ex: Exception): unit = let maybeRpcTimeoutException = - FSharpUtil.FindException ex + FSharpUtil.FindException ex match maybeRpcTimeoutException with | Some rpcTimeoutEx -> raise <| ServerTimedOutException(exMsg, rpcTimeoutEx) @@ -260,7 +261,7 @@ module Server = // this could be a Xamarin.Android bug (see https://gitlab.com/nblockchain/geewallet/issues/119) let MaybeRethrowObjectDisposedException (ex: Exception): unit = - let maybeRpcUnknownEx = FSharpUtil.FindException ex + let maybeRpcUnknownEx = FSharpUtil.FindException ex match maybeRpcUnknownEx with | Some _ -> let maybeObjectDisposedEx = FSharpUtil.FindException ex @@ -274,12 +275,12 @@ module Server = () let MaybeRethrowInnerRpcException (ex: Exception): unit = - let maybeRpcUnknownEx = FSharpUtil.FindException ex + let maybeRpcUnknownEx = FSharpUtil.FindException ex match maybeRpcUnknownEx with | Some rpcUnknownEx -> let maybeDeSerializationEx = - FSharpUtil.FindException rpcUnknownEx + FSharpUtil.FindException rpcUnknownEx match maybeDeSerializationEx with | None -> () @@ -411,10 +412,10 @@ module Server = return raise <| FSharpUtil.ReRaise ex } - let connectionTimeout = Config.DEFAULT_NETWORK_TIMEOUT + ClientBase.ConnectionTimeout <- Config.DEFAULT_NETWORK_TIMEOUT async { - let web3Server = Web3Server (connectionTimeout, server) + let web3Server = Web3Server (server) try return! HandlePossibleEtherFailures (web3ClientFunc web3Server) @@ -692,7 +693,7 @@ module Server = web3Funcs with | ex -> - match FSharpUtil.FindException ex with + match FSharpUtil.FindException ex with | None -> return raise (FSharpUtil.ReRaise ex) | Some rpcResponseException -> diff --git a/src/GWallet.Backend/Ether/TokenManager.fs b/src/GWallet.Backend/Ether/TokenManager.fs index ed00b7f22..015c0b036 100644 --- a/src/GWallet.Backend/Ether/TokenManager.fs +++ b/src/GWallet.Backend/Ether/TokenManager.fs @@ -47,6 +47,6 @@ module TokenManager = // this is a dummy instance we need in order to pass it to base class of StandardTokenService, but not // really used online; FIXME: propose "Web3-less" overload to Nethereum - let private dummyOfflineWeb3 = Web3 Config.DEFAULT_NETWORK_TIMEOUT + let private dummyOfflineWeb3 = Web3() type OfflineTokenServiceWrapper(currency: Currency) = inherit TokenServiceWrapper(dummyOfflineWeb3, currency) diff --git a/src/GWallet.Backend/GWallet.Backend-legacy.fsproj b/src/GWallet.Backend/GWallet.Backend-legacy.fsproj index dc11f1779..59eb2c1aa 100644 --- a/src/GWallet.Backend/GWallet.Backend-legacy.fsproj +++ b/src/GWallet.Backend/GWallet.Backend-legacy.fsproj @@ -236,7 +236,7 @@ - ..\..\packages\Microsoft.Extensions.Logging.Abstractions.1.0.2\lib\netstandard1.1\Microsoft.Extensions.Logging.Abstractions.dll + ..\..\packages\Microsoft.Extensions.Logging.Abstractions.6.0.0\lib\net461\Microsoft.Extensions.Logging.Abstractions.dll ..\..\packages\JsonRpcSharp.0.98.0--date20230731-1252.git-6788e32\lib\netstandard2.0\JsonRpcSharp.TcpClient.dll @@ -262,38 +262,59 @@ ..\..\packages\JsonRpcSharp.0.98.0--date20230731-1252.git-6788e32\lib\netstandard2.0\JsonRpcSharp.WebSocketClient.dll + + ..\..\packages\ADRaffy.ENSNormalize.0.1.5\lib\net461\ADRaffy.ENSNormalize.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.BlockchainProcessing.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.JsonRpc.Client.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.JsonRpc.RpcClient.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Merkle.Patricia.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Model.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Signer.EIP712.dll + - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.ABI.dll + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.ABI.dll - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.Accounts.dll + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Accounts.dll - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.Contracts.dll + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Contracts.dll - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.Hex.dll + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Hex.dll - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.KeyStore.dll + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.KeyStore.dll - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.RLP.dll + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.RLP.dll - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.RPC.dll + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.RPC.dll - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.Signer.dll + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Signer.dll - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.StandardTokenEIP20.dll + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.StandardTokenEIP20.dll - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.Util.dll + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Util.dll - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.Web3.dll + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Web3.dll ..\..\packages\HtmlAgilityPack.1.11.24\lib\Net45\HtmlAgilityPack.dll @@ -315,4 +336,5 @@ --> + diff --git a/src/GWallet.Backend/GWallet.Backend.fsproj b/src/GWallet.Backend/GWallet.Backend.fsproj index e1bdf08ff..2e3358448 100644 --- a/src/GWallet.Backend/GWallet.Backend.fsproj +++ b/src/GWallet.Backend/GWallet.Backend.fsproj @@ -69,7 +69,10 @@ - + + + + diff --git a/src/GWallet.Backend/packages.config b/src/GWallet.Backend/packages.config index aa604ee0d..72622ad9b 100644 --- a/src/GWallet.Backend/packages.config +++ b/src/GWallet.Backend/packages.config @@ -1,5 +1,6 @@  + @@ -8,12 +9,12 @@ - + - + diff --git a/src/GWallet.Frontend.Console/App.config b/src/GWallet.Frontend.Console/App.config index 1778ee567..41a83fbc6 100644 --- a/src/GWallet.Frontend.Console/App.config +++ b/src/GWallet.Frontend.Console/App.config @@ -14,6 +14,18 @@ + + + + + + + + + + + + diff --git a/src/GWallet.Frontend.XF.Android/GWallet.Frontend.XF.Android.fsproj b/src/GWallet.Frontend.XF.Android/GWallet.Frontend.XF.Android.fsproj index 1b60db231..b2886b6aa 100644 --- a/src/GWallet.Frontend.XF.Android/GWallet.Frontend.XF.Android.fsproj +++ b/src/GWallet.Frontend.XF.Android/GWallet.Frontend.XF.Android.fsproj @@ -49,6 +49,66 @@ + + ..\..\packages\ADRaffy.ENSNormalize.0.1.5\lib\netstandard2.0\ADRaffy.ENSNormalize.dll + + + ..\..\packages\Microsoft.Extensions.Logging.Abstractions.6.0.0\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.ABI.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Accounts.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.BlockchainProcessing.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Contracts.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Hex.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.JsonRpc.Client.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.JsonRpc.RpcClient.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.KeyStore.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Merkle.Patricia.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Model.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.RLP.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.RPC.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Signer.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Signer.EIP712.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.StandardTokenEIP20.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Util.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Web3.dll + @@ -290,48 +350,12 @@ ..\..\packages\JsonRpcSharp.0.98.0--date20230731-1252.git-6788e32\lib\netstandard2.0\JsonRpcSharp.WebSocketClient.dll - - ..\..\packages\Microsoft.Extensions.Logging.Abstractions.1.0.2\lib\netstandard1.1\Microsoft.Extensions.Logging.Abstractions.dll - ..\..\packages\NBitcoin.6.0.17\lib\netstandard2.1\NBitcoin.dll ..\..\packages\NBitcoin.Altcoins.3.0.8\lib\netstandard2.1\NBitcoin.Altcoins.dll - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.ABI.dll - - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.Accounts.dll - - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.Contracts.dll - - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.Hex.dll - - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.KeyStore.dll - - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.RLP.dll - - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.RPC.dll - - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.Signer.dll - - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.StandardTokenEIP20.dll - - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.Util.dll - - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.Web3.dll - ..\..\packages\Newtonsoft.Json.13.0.2\lib\netstandard2.0\Newtonsoft.Json.dll @@ -556,6 +580,7 @@ + @@ -665,4 +690,5 @@ + diff --git a/src/GWallet.Frontend.XF.Android/packages.config b/src/GWallet.Frontend.XF.Android/packages.config index 87848d06f..d716aa8a0 100644 --- a/src/GWallet.Frontend.XF.Android/packages.config +++ b/src/GWallet.Frontend.XF.Android/packages.config @@ -1,5 +1,6 @@  + @@ -9,12 +10,12 @@ - + - + diff --git a/src/GWallet.Frontend.XF.Gtk/GWallet.Frontend.XF.Gtk.fsproj b/src/GWallet.Frontend.XF.Gtk/GWallet.Frontend.XF.Gtk.fsproj index ce3686c54..0dde30253 100644 --- a/src/GWallet.Frontend.XF.Gtk/GWallet.Frontend.XF.Gtk.fsproj +++ b/src/GWallet.Frontend.XF.Gtk/GWallet.Frontend.XF.Gtk.fsproj @@ -36,7 +36,67 @@ $(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets + + ..\..\packages\ADRaffy.ENSNormalize.0.1.5\lib\net461\ADRaffy.ENSNormalize.dll + + + ..\..\packages\Microsoft.Extensions.Logging.Abstractions.6.0.0\lib\net461\Microsoft.Extensions.Logging.Abstractions.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.ABI.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Accounts.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.BlockchainProcessing.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Contracts.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Hex.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.JsonRpc.Client.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.JsonRpc.RpcClient.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.KeyStore.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Merkle.Patricia.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Model.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.RLP.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.RPC.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Signer.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Signer.EIP712.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.StandardTokenEIP20.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Util.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Web3.dll + @@ -130,9 +190,6 @@ ..\..\packages\ZXing.Net.Xamarin.Forms.3.0.0--date20220902-0549.git-462686e\lib\netstandard2.0\ZXing.Net.Mobile.Forms.dll - - ..\..\packages\Microsoft.Extensions.Logging.Abstractions.1.0.2\lib\netstandard1.1\Microsoft.Extensions.Logging.Abstractions.dll - ..\..\packages\System.IO.Pipes.4.3.0\lib\net46\System.IO.Pipes.dll @@ -160,39 +217,6 @@ ..\..\packages\JsonRpcSharp.0.98.0--date20230731-1252.git-6788e32\lib\netstandard2.0\JsonRpcSharp.WebSocketClient.dll - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.ABI.dll - - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.Accounts.dll - - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.Contracts.dll - - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.Hex.dll - - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.KeyStore.dll - - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.RLP.dll - - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.RPC.dll - - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.Signer.dll - - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.StandardTokenEIP20.dll - - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.Util.dll - - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.Web3.dll - ..\..\packages\HtmlAgilityPack.1.11.24\lib\Net45\HtmlAgilityPack.dll @@ -260,4 +284,11 @@ + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105.The missing file is {0}. + + + diff --git a/src/GWallet.Frontend.XF.Gtk/packages.config b/src/GWallet.Frontend.XF.Gtk/packages.config index a96baa6b8..5398c3033 100644 --- a/src/GWallet.Frontend.XF.Gtk/packages.config +++ b/src/GWallet.Frontend.XF.Gtk/packages.config @@ -1,5 +1,6 @@  + @@ -9,10 +10,10 @@ - + - + diff --git a/src/GWallet.Frontend.XF.Mac/GWallet.Frontend.XF.Mac.fsproj b/src/GWallet.Frontend.XF.Mac/GWallet.Frontend.XF.Mac.fsproj index 31032e2a0..1bc8001e7 100644 --- a/src/GWallet.Frontend.XF.Mac/GWallet.Frontend.XF.Mac.fsproj +++ b/src/GWallet.Frontend.XF.Mac/GWallet.Frontend.XF.Mac.fsproj @@ -49,6 +49,66 @@ + + ..\..\packages\ADRaffy.ENSNormalize.0.1.5\lib\netstandard2.0\ADRaffy.ENSNormalize.dll + + + ..\..\packages\Microsoft.Extensions.Logging.Abstractions.6.0.0\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.ABI.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Accounts.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.BlockchainProcessing.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Contracts.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Hex.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.JsonRpc.Client.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.JsonRpc.RpcClient.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.KeyStore.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Merkle.Patricia.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Model.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.RLP.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.RPC.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Signer.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Signer.EIP712.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.StandardTokenEIP20.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Util.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Web3.dll + @@ -117,9 +177,6 @@ ..\..\packages\FSharp.Core.4.7.0\lib\netstandard2.0\FSharp.Core.dll - - ..\..\packages\Microsoft.Extensions.Logging.Abstractions.1.0.2\lib\netstandard1.1\Microsoft.Extensions.Logging.Abstractions.dll - ..\..\packages\JsonRpcSharp.0.98.0--date20230731-1252.git-6788e32\lib\netstandard2.0\JsonRpcSharp.Client.dll @@ -135,39 +192,6 @@ ..\..\packages\JsonRpcSharp.0.98.0--date20230731-1252.git-6788e32\lib\netstandard2.0\JsonRpcSharp.WebSocketClient.dll - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.ABI.dll - - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.Accounts.dll - - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.Contracts.dll - - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.Hex.dll - - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.KeyStore.dll - - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.RLP.dll - - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.RPC.dll - - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.Signer.dll - - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.StandardTokenEIP20.dll - - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.Util.dll - - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.Web3.dll - ..\..\packages\HtmlAgilityPack.1.11.24\lib\netstandard2.0\HtmlAgilityPack.dll @@ -222,4 +246,11 @@ + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105.The missing file is {0}. + + + diff --git a/src/GWallet.Frontend.XF.Mac/packages.config b/src/GWallet.Frontend.XF.Mac/packages.config index 51a86c052..e1e920ed7 100644 --- a/src/GWallet.Frontend.XF.Mac/packages.config +++ b/src/GWallet.Frontend.XF.Mac/packages.config @@ -1,5 +1,6 @@  + @@ -8,12 +9,12 @@ - + - + diff --git a/src/GWallet.Frontend.XF.iOS/GWallet.Frontend.XF.iOS.fsproj b/src/GWallet.Frontend.XF.iOS/GWallet.Frontend.XF.iOS.fsproj index 3d8017712..cc6ddf8b4 100644 --- a/src/GWallet.Frontend.XF.iOS/GWallet.Frontend.XF.iOS.fsproj +++ b/src/GWallet.Frontend.XF.iOS/GWallet.Frontend.XF.iOS.fsproj @@ -153,6 +153,66 @@ + + ..\..\packages\ADRaffy.ENSNormalize.0.1.5\lib\netstandard2.0\ADRaffy.ENSNormalize.dll + + + ..\..\packages\Microsoft.Extensions.Logging.Abstractions.6.0.0\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.ABI.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Accounts.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.BlockchainProcessing.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Contracts.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Hex.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.JsonRpc.Client.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.JsonRpc.RpcClient.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.KeyStore.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Merkle.Patricia.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Model.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.RLP.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.RPC.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Signer.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Signer.EIP712.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.StandardTokenEIP20.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Util.dll + + + ..\..\packages\Nethereum.3.99.0--date20231003-1147.git-b9a16cf\lib\netstandard2.0\Nethereum.Web3.dll + @@ -226,9 +286,6 @@ ..\..\packages\FSharp.Core.4.7.0\lib\netstandard2.0\FSharp.Core.dll - - ..\..\packages\Microsoft.Extensions.Logging.Abstractions.1.0.2\lib\netstandard1.1\Microsoft.Extensions.Logging.Abstractions.dll - ..\..\packages\JsonRpcSharp.0.98.0--date20230731-1252.git-6788e32\lib\netstandard2.0\JsonRpcSharp.Client.dll @@ -244,39 +301,6 @@ ..\..\packages\JsonRpcSharp.0.98.0--date20230731-1252.git-6788e32\lib\netstandard2.0\JsonRpcSharp.WebSocketClient.dll - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.ABI.dll - - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.Accounts.dll - - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.Contracts.dll - - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.Hex.dll - - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.KeyStore.dll - - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.RLP.dll - - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.RPC.dll - - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.Signer.dll - - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.StandardTokenEIP20.dll - - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.Util.dll - - - ..\..\packages\Nethereum.0.95.0--date20210125-0551.git-05a29e9\lib\netstandard2.0\Nethereum.Web3.dll - ..\..\packages\HtmlAgilityPack.1.11.24\lib\netstandard2.0\HtmlAgilityPack.dll @@ -295,4 +319,11 @@ + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105.The missing file is {0}. + + + diff --git a/src/GWallet.Frontend.XF.iOS/packages.config b/src/GWallet.Frontend.XF.iOS/packages.config index a8e21708f..1c84d4f6b 100644 --- a/src/GWallet.Frontend.XF.iOS/packages.config +++ b/src/GWallet.Frontend.XF.iOS/packages.config @@ -1,5 +1,6 @@  + @@ -8,12 +9,12 @@ - + - + From cd9e2e82944d27f87eb482bd0865f7a743843d98 Mon Sep 17 00:00:00 2001 From: Afshin Arani Date: Wed, 11 Oct 2023 13:28:31 +0330 Subject: [PATCH 3/3] Backend,Frontend,Tests: rm txDetail from SignedTx This commit removes the redundant proposal and metadata from the SignedTransaction type. --- src/GWallet.Backend.Tests/Deserialization.fs | 164 ++++++++---------- .../GWallet.Backend.Tests-legacy.fsproj | 2 +- .../GWallet.Backend.Tests.fsproj | 2 +- src/GWallet.Backend.Tests/MarshallingData.fs | 21 ++- src/GWallet.Backend.Tests/Serialization.fs | 8 +- .../signedAndFormattedBtcTransaction.json | 67 +------ .../signedAndFormattedDaiTransaction.json | 13 ++ .../signedAndFormattedEtherTransaction.json | 50 +----- .../signedAndFormattedSaiTransaction.json | 60 ------- src/GWallet.Backend/Account.fs | 114 ++++++------ src/GWallet.Backend/Ether/EtherAccount.fs | 114 +++++++----- src/GWallet.Backend/Ether/TokenManager.fs | 35 +++- src/GWallet.Backend/Transaction.fs | 14 +- .../UtxoCoin/UtxoCoinAccount.fs | 91 ++++++++-- src/GWallet.Frontend.Console/Program.fs | 7 +- src/GWallet.Frontend.XF/SendPage.xaml.fs | 16 +- 16 files changed, 377 insertions(+), 401 deletions(-) create mode 100644 src/GWallet.Backend.Tests/data/signedAndFormattedDaiTransaction.json delete mode 100644 src/GWallet.Backend.Tests/data/signedAndFormattedSaiTransaction.json diff --git a/src/GWallet.Backend.Tests/Deserialization.fs b/src/GWallet.Backend.Tests/Deserialization.fs index a7b7866e6..47fe7ad93 100644 --- a/src/GWallet.Backend.Tests/Deserialization.fs +++ b/src/GWallet.Backend.Tests/Deserialization.fs @@ -96,83 +96,71 @@ type Deserialization() = [] member __.``signed btc transaction import``() = - let deserializedSignedTrans: SignedTransaction = + let deserializedSignedTrans: SignedTransaction = Account.ImportSignedTransactionFromJson MarshallingData.SignedBtcTransactionExampleInJson + // Validate deserialized SignedTranasction Assert.That(deserializedSignedTrans, Is.Not.Null) + Assert.That(deserializedSignedTrans.Currency, Is.EqualTo Currency.BTC) + Assert.That(deserializedSignedTrans.FeeCurrency, Is.EqualTo Currency.BTC) Assert.That(deserializedSignedTrans.RawTransaction, - Is.EqualTo "0200000000010111b6e0460bb810b05744f8d38262f95fbab02b168b070598a6f31fad438fced4000000001716001427c106013c0042da165c082b3870c31fb3ab4683feffffff0200ca9a3b0000000017a914d8b6fcc85a383261df05423ddf068a8987bf0287873067a3fa0100000017a914d5df0b9ca6c0e1ba60a9ff29359d2600d9c6659d870247304402203b85cb05b43cc68df72e2e54c6cb508aa324a5de0c53f1bbfe997cbd7509774d022041e1b1823bdaddcd6581d7cde6e6a4c4dbef483e42e59e04dbacbaf537c3e3e8012103fbbdb3b3fc3abbbd983b20a557445fb041d6f21cc5977d2121971cb1ce5298978c000000") - - Assert.That(deserializedSignedTrans.TransactionInfo, Is.Not.Null) - Assert.That(deserializedSignedTrans.TransactionInfo.Proposal, Is.Not.Null) - Assert.That(deserializedSignedTrans.TransactionInfo.Cache, Is.Not.Null) - Assert.That(deserializedSignedTrans.TransactionInfo.Metadata, Is.Not.Null) - - Assert.That(deserializedSignedTrans.TransactionInfo.Proposal.Amount.ValueToSend, - Is.EqualTo(10.01m)) - Assert.That(deserializedSignedTrans.TransactionInfo.Proposal.Amount.BalanceAtTheMomentOfSending, - Is.EqualTo 12.02m) - Assert.That(deserializedSignedTrans.TransactionInfo.Proposal.Amount.Currency, - Is.EqualTo(Currency.BTC)) - Assert.That(deserializedSignedTrans.TransactionInfo.Proposal.DestinationAddress, - Is.EqualTo("13jxHQDxGto46QhjFiMb78dZdys9ZD8vW5")) - Assert.That(deserializedSignedTrans.TransactionInfo.Proposal.OriginAddress, - Is.EqualTo("16pKBjGGZkUXo1afyBNf5ttFvV9hauS1kR")) - - let btcTxMetadata = deserializedSignedTrans.TransactionInfo.Metadata :?> UtxoCoin.TransactionMetadata - Assert.That(btcTxMetadata.Fee.EstimatedFeeInSatoshis, Is.EqualTo 10) - Assert.That(btcTxMetadata.Inputs.Length, Is.EqualTo 1) - Assert.That(deserializedSignedTrans.TransactionInfo.Metadata.FeeEstimationTime, - Is.EqualTo MarshallingData.SomeDate) - - Assert.That(deserializedSignedTrans.TransactionInfo.Cache.Balances.Count, - Is.EqualTo 5) - Assert.That(deserializedSignedTrans.TransactionInfo.Cache.UsdPrice.Count, - Is.EqualTo 5) - + Is.EqualTo "01000000000102cd9e4c06746721fe5d0ecdeabe29a0f05cc22bd7013ff76132efe476d9346bdc0000000017160014618869483590d6c1afe51160f244982e055d213ffdffffffef2763e4690975dc9415d36c06361ddee8393e6d9d86edd748ca21f10788fbc30100000017160014618869483590d6c1afe51160f244982e055d213ffdffffff01ba89000000000000220020574712746ca1942b8f0e3d52e4c1fd9406c3e1b602b328a2a77a57c233fed4640247304402206e9359074007c597a8243d4e5bbfb18ccfd83c0206fcbd1fafc02eb4946852f90220566e0d719b48d11f193d5d6d80eccbaaf44ee1771bf9ea7fd3810d41c5cb429f012102b7326aff8f2e56a341c31fbf50d0ce1a641859d837daffd7bf03f1f80a8c5eaa0247304402202fdbb2ea123c1150b26835ecd54cd59a22bca6a47f32167b35f355fbfcc12d22022011b8314e51b229d6d5a5ee216c9e038b5e05d1b5123485b935a1f823f2bf2279012102b7326aff8f2e56a341c31fbf50d0ce1a641859d837daffd7bf03f1f80a8c5eaa00000000") + + // Can't validate proposal because of "unknown origin account" error + + let btcTxMetadata = + Account.GetTransactionMetadata deserializedSignedTrans + |> Async.RunSynchronously + :?> UtxoCoin.TransactionMetadata + + Assert.That(btcTxMetadata.Fee.EstimatedFeeInSatoshis, Is.EqualTo 980) + Assert.That(btcTxMetadata.Inputs.Length, Is.EqualTo 2) + [] member __.``signed ether transaction import``() = - let deserializedSignedTrans: SignedTransaction = + let deserializedSignedTrans: SignedTransaction = Account.ImportSignedTransactionFromJson MarshallingData.SignedEtherTransactionExampleInJson + // Validate deserialized SignedTransaction Assert.That(deserializedSignedTrans, Is.Not.Null) Assert.That(deserializedSignedTrans.RawTransaction, - Is.EqualTo("doijfsoifjdosisdjfomirmjosmi")) - - Assert.That(deserializedSignedTrans.TransactionInfo, Is.Not.Null) - Assert.That(deserializedSignedTrans.TransactionInfo.Proposal, Is.Not.Null) - Assert.That(deserializedSignedTrans.TransactionInfo.Cache, Is.Not.Null) - Assert.That(deserializedSignedTrans.TransactionInfo.Metadata, Is.Not.Null) + Is.EqualTo("f86b0185019d334a3482520894d2fdfa29d5ccbb8168ba248d59ded7a25396f84e87022a8ad81f98768026a06bb7c1f8f2b40ed2bc3a3b572cdde7fddb42a8d43c561c60580183b0ed8c2d9fa035183359feab8789642135a253371f80781f4a870f0cae8a7368c5d7e102a688")) - Assert.That(deserializedSignedTrans.TransactionInfo.Proposal.Amount.ValueToSend, - Is.EqualTo(10.01m)) - Assert.That(deserializedSignedTrans.TransactionInfo.Proposal.Amount.BalanceAtTheMomentOfSending, - Is.EqualTo 12.02m) - Assert.That(deserializedSignedTrans.TransactionInfo.Proposal.Amount.Currency, - Is.EqualTo(Currency.ETC)) - Assert.That(deserializedSignedTrans.TransactionInfo.Proposal.DestinationAddress, - Is.EqualTo("0xf3j4m0rjxdddud9403j")) - Assert.That(deserializedSignedTrans.TransactionInfo.Proposal.OriginAddress, - Is.EqualTo("0xf3j4m0rjx94sushh03j")) + Assert.That(deserializedSignedTrans.Currency, + Is.EqualTo(Currency.ETH)) + + Assert.That(deserializedSignedTrans.FeeCurrency, + Is.EqualTo(Currency.ETH)) - let etherTxMetadata = deserializedSignedTrans.TransactionInfo.Metadata :?> Ether.TransactionMetadata - Assert.That(etherTxMetadata.TransactionCount, Is.EqualTo(69)) + + // Validate generated proposal + let proposal = Account.GetTransactionProposal deserializedSignedTrans + + Assert.That(proposal.Amount.ValueToSend, + Is.EqualTo(0.000609725773224054m)) + Assert.That(proposal.Amount.Currency, + Is.EqualTo(Currency.ETH)) + Assert.That(proposal.DestinationAddress, + Is.EqualTo("0xd2FDFA29D5ccbb8168Ba248D59dED7a25396f84E")) + Assert.That(proposal.OriginAddress, + Is.EqualTo("0xc295DDB9B89AFb7B0b23cFb76cb34ce33bc854D5")) + + // Validate generated metadata + let etherTxMetadata = + Account.GetTransactionMetadata deserializedSignedTrans + |> Async.RunSynchronously + :?> Ether.TransactionMetadata + + Assert.That(etherTxMetadata.TransactionCount, Is.EqualTo(1)) Assert.That(etherTxMetadata.Fee.Currency, - Is.EqualTo(Currency.ETC)) + Is.EqualTo(Currency.ETH)) Assert.That(etherTxMetadata.Fee.GasPriceInWei, - Is.EqualTo(6969)) - Assert.That(deserializedSignedTrans.TransactionInfo.Metadata.FeeEstimationTime, - Is.EqualTo MarshallingData.SomeDate) - - Assert.That(deserializedSignedTrans.TransactionInfo.Cache.Balances.Count, - Is.EqualTo(2)) - Assert.That(deserializedSignedTrans.TransactionInfo.Cache.UsdPrice.Count, - Is.EqualTo(2)) + Is.EqualTo(6932351540UL)) [] member __.``unsigned SAI transaction import``() = @@ -205,46 +193,48 @@ type Deserialization() = Assert.That(deserializedUnsignedTrans.Cache.UsdPrice.Count, Is.EqualTo(5)) [] - member __.``signed SAI transaction import``() = + member __.``signed DAI transaction import``() = - let deserializedSignedTrans: SignedTransaction = + let deserializedSignedTrans: SignedTransaction = Account.ImportSignedTransactionFromJson - MarshallingData.SignedSaiTransactionExampleInJson + MarshallingData.SignedDaiTransactionExampleInJson + // Validate deserialized SignedTransaction Assert.That(deserializedSignedTrans, Is.Not.Null) Assert.That(deserializedSignedTrans.RawTransaction, - Is.EqualTo("f8a80784c74d93708291b29489d24a6b4ccb1b6faa2625fe562bdd9a2326035980b844a9059cbb000000000000000000000000db0381b1a380d8db2724a9ca2d33e0c6c044be3b0000000000000000000000000000000000000000000000000de0b6b3a764000026a072cdeb03affd5977c76366efbc1405fbb4fa997ce72c1e4554ba9ec5ef772ddca069d522ea304efebd2537330870bc1ca9e9a6fe3eb5f8d8f66c1b82d9fc27a4bf")) + Is.EqualTo("f8a90185016c653675828792946b175474e89094c44da98b954eedeac495271d0f80b844a9059cbb000000000000000000000000d2fdfa29d5ccbb8168ba248d59ded7a25396f84e0000000000000000000000000000000000000000000000000de0b6b3a764000026a0d5c49133f38f3b60aa41747a4b7cc300a6dac87803b82ba23af9a97fd5994c3ea03122864fd6b294a3da2f3827e70fa861838a168f6533e03587358a6bdc594235")) - Assert.That(deserializedSignedTrans.TransactionInfo, Is.Not.Null) - Assert.That(deserializedSignedTrans.TransactionInfo.Proposal, Is.Not.Null) - Assert.That(deserializedSignedTrans.TransactionInfo.Cache, Is.Not.Null) - Assert.That(deserializedSignedTrans.TransactionInfo.Metadata, Is.Not.Null) - - Assert.That(deserializedSignedTrans.TransactionInfo.Proposal.Amount.ValueToSend, - Is.EqualTo(1m)) - Assert.That(deserializedSignedTrans.TransactionInfo.Proposal.Amount.BalanceAtTheMomentOfSending, - Is.EqualTo 7.08m) - Assert.That(deserializedSignedTrans.TransactionInfo.Proposal.Amount.Currency, - Is.EqualTo Currency.SAI) - Assert.That(deserializedSignedTrans.TransactionInfo.Proposal.DestinationAddress, - Is.EqualTo("0xDb0381B1a380d8db2724A9Ca2d33E0C6C044bE3b")) - Assert.That(deserializedSignedTrans.TransactionInfo.Proposal.OriginAddress, - Is.EqualTo("0xba766d6d13E2Cc921Bf6e896319D32502af9e37E")) - - let etherTxMetadata = deserializedSignedTrans.TransactionInfo.Metadata :?> Ether.TransactionMetadata - Assert.That(etherTxMetadata.TransactionCount, Is.EqualTo(7)) + Assert.That(deserializedSignedTrans.Currency, + Is.EqualTo Currency.DAI) + + Assert.That(deserializedSignedTrans.FeeCurrency, + Is.EqualTo(Currency.ETH)) + + // Validate generated proposal + let proposal = Account.GetTransactionProposal deserializedSignedTrans + + Assert.That(proposal.Amount.ValueToSend, + Is.EqualTo(1.0m)) + Assert.That(proposal.Amount.Currency, + Is.EqualTo(Currency.DAI)) + Assert.That(proposal.DestinationAddress, + Is.EqualTo("0xd2FDFA29D5ccbb8168Ba248D59dED7a25396f84E")) + Assert.That(proposal.OriginAddress, + Is.EqualTo("0xc295DDB9B89AFb7B0b23cFb76cb34ce33bc854D5")) + + // Validate generated metadata + let etherTxMetadata = + Account.GetTransactionMetadata deserializedSignedTrans + |> Async.RunSynchronously + :?> Ether.TransactionMetadata + + Assert.That(etherTxMetadata.TransactionCount, Is.EqualTo(1)) Assert.That(etherTxMetadata.Fee.Currency, Is.EqualTo(Currency.ETH)) Assert.That(etherTxMetadata.Fee.GasPriceInWei, - Is.EqualTo(3343750000L)) - Assert.That(deserializedSignedTrans.TransactionInfo.Metadata.FeeEstimationTime, - Is.EqualTo MarshallingData.SomeDate) + Is.EqualTo(6113539701UL)) - Assert.That(deserializedSignedTrans.TransactionInfo.Cache.Balances.Count, - Is.EqualTo 5) - Assert.That(deserializedSignedTrans.TransactionInfo.Cache.UsdPrice.Count, - Is.EqualTo(5)) [] member __.``can roundtrip currency``() = diff --git a/src/GWallet.Backend.Tests/GWallet.Backend.Tests-legacy.fsproj b/src/GWallet.Backend.Tests/GWallet.Backend.Tests-legacy.fsproj index ffa447184..9e178dbdf 100644 --- a/src/GWallet.Backend.Tests/GWallet.Backend.Tests-legacy.fsproj +++ b/src/GWallet.Backend.Tests/GWallet.Backend.Tests-legacy.fsproj @@ -68,7 +68,7 @@ - + diff --git a/src/GWallet.Backend.Tests/GWallet.Backend.Tests.fsproj b/src/GWallet.Backend.Tests/GWallet.Backend.Tests.fsproj index 7407d1b20..a36bf095f 100644 --- a/src/GWallet.Backend.Tests/GWallet.Backend.Tests.fsproj +++ b/src/GWallet.Backend.Tests/GWallet.Backend.Tests.fsproj @@ -51,7 +51,7 @@ - + diff --git a/src/GWallet.Backend.Tests/MarshallingData.fs b/src/GWallet.Backend.Tests/MarshallingData.fs index e8f27c0cf..f717a9a8d 100644 --- a/src/GWallet.Backend.Tests/MarshallingData.fs +++ b/src/GWallet.Backend.Tests/MarshallingData.fs @@ -41,8 +41,8 @@ module MarshallingData = let UnsignedSaiTransactionExampleInJson = ReadEmbeddedResource "unsignedAndFormattedSaiTransaction.json" - let SignedSaiTransactionExampleInJson = - ReadEmbeddedResource "signedAndFormattedSaiTransaction.json" + let SignedDaiTransactionExampleInJson = + ReadEmbeddedResource "signedAndFormattedDaiTransaction.json" let BasicExceptionExampleInJson = ReadEmbeddedResource "basicException.json" @@ -257,8 +257,9 @@ module MarshallingData = let SignedBtcTransactionExample = { - TransactionInfo = UnsignedBtcTransactionExample; - RawTransaction = "0200000000010111b6e0460bb810b05744f8d38262f95fbab02b168b070598a6f31fad438fced4000000001716001427c106013c0042da165c082b3870c31fb3ab4683feffffff0200ca9a3b0000000017a914d8b6fcc85a383261df05423ddf068a8987bf0287873067a3fa0100000017a914d5df0b9ca6c0e1ba60a9ff29359d2600d9c6659d870247304402203b85cb05b43cc68df72e2e54c6cb508aa324a5de0c53f1bbfe997cbd7509774d022041e1b1823bdaddcd6581d7cde6e6a4c4dbef483e42e59e04dbacbaf537c3e3e8012103fbbdb3b3fc3abbbd983b20a557445fb041d6f21cc5977d2121971cb1ce5298978c000000"; + Currency = Currency.BTC + FeeCurrency = Currency.BTC + RawTransaction = "01000000000102cd9e4c06746721fe5d0ecdeabe29a0f05cc22bd7013ff76132efe476d9346bdc0000000017160014618869483590d6c1afe51160f244982e055d213ffdffffffef2763e4690975dc9415d36c06361ddee8393e6d9d86edd748ca21f10788fbc30100000017160014618869483590d6c1afe51160f244982e055d213ffdffffff01ba89000000000000220020574712746ca1942b8f0e3d52e4c1fd9406c3e1b602b328a2a77a57c233fed4640247304402206e9359074007c597a8243d4e5bbfb18ccfd83c0206fcbd1fafc02eb4946852f90220566e0d719b48d11f193d5d6d80eccbaaf44ee1771bf9ea7fd3810d41c5cb429f012102b7326aff8f2e56a341c31fbf50d0ce1a641859d837daffd7bf03f1f80a8c5eaa0247304402202fdbb2ea123c1150b26835ecd54cd59a22bca6a47f32167b35f355fbfcc12d22022011b8314e51b229d6d5a5ee216c9e038b5e05d1b5123485b935a1f823f2bf2279012102b7326aff8f2e56a341c31fbf50d0ce1a641859d837daffd7bf03f1f80a8c5eaa00000000"; } let SignedBtcTransactionExampleInJson = @@ -303,10 +304,11 @@ module MarshallingData = Cache = realCachingDataExample; Metadata = someSaiTxMetadata } - let SignedSaiTransactionExample = + let SignedDaiTransactionExample = { - TransactionInfo = someSaiTransactionInfo - RawTransaction = "f8a80784c74d93708291b29489d24a6b4ccb1b6faa2625fe562bdd9a2326035980b844a9059cbb000000000000000000000000db0381b1a380d8db2724a9ca2d33e0c6c044be3b0000000000000000000000000000000000000000000000000de0b6b3a764000026a072cdeb03affd5977c76366efbc1405fbb4fa997ce72c1e4554ba9ec5ef772ddca069d522ea304efebd2537330870bc1ca9e9a6fe3eb5f8d8f66c1b82d9fc27a4bf"; + Currency = Currency.DAI + FeeCurrency = Currency.ETH + RawTransaction = "f8a90185016c653675828792946b175474e89094c44da98b954eedeac495271d0f80b844a9059cbb000000000000000000000000d2fdfa29d5ccbb8168ba248d59ded7a25396f84e0000000000000000000000000000000000000000000000000de0b6b3a764000026a0d5c49133f38f3b60aa41747a4b7cc300a6dac87803b82ba23af9a97fd5994c3ea03122864fd6b294a3da2f3827e70fa861838a168f6533e03587358a6bdc594235"; } let someEtherTransactionInfo = @@ -317,8 +319,9 @@ module MarshallingData = } let SignedEtherTransactionExample = { - TransactionInfo = someEtherTransactionInfo; - RawTransaction = "doijfsoifjdosisdjfomirmjosmi"; + Currency = Currency.ETH + FeeCurrency = Currency.ETH + RawTransaction = "f86b0185019d334a3482520894d2fdfa29d5ccbb8168ba248d59ded7a25396f84e87022a8ad81f98768026a06bb7c1f8f2b40ed2bc3a3b572cdde7fddb42a8d43c561c60580183b0ed8c2d9fa035183359feab8789642135a253371f80781f4a870f0cae8a7368c5d7e102a688"; } let SignedEtherTransactionExampleInJson = ReadEmbeddedResource "signedAndFormattedEtherTransaction.json" diff --git a/src/GWallet.Backend.Tests/Serialization.fs b/src/GWallet.Backend.Tests/Serialization.fs index afc048db4..0bbbf4903 100644 --- a/src/GWallet.Backend.Tests/Serialization.fs +++ b/src/GWallet.Backend.Tests/Serialization.fs @@ -76,16 +76,16 @@ type Serialization() = [] member __.``signed SAI transaction export``() = - let json = Account.ExportUnsignedTransactionToJson MarshallingData.SignedSaiTransactionExample + let json = Account.ExportUnsignedTransactionToJson MarshallingData.SignedDaiTransactionExample Assert.That(json, Is.Not.Null) Assert.That(json, Is.Not.Empty) Assert.That(json|> MarshallingData.Sanitize, - Is.EqualTo MarshallingData.SignedSaiTransactionExampleInJson) + Is.EqualTo MarshallingData.SignedDaiTransactionExampleInJson) [] member __.``can serialize exceptions``() = - let json = Account.ExportUnsignedTransactionToJson MarshallingData.SignedSaiTransactionExample + let json = Account.ExportUnsignedTransactionToJson MarshallingData.SignedDaiTransactionExample Assert.That(json, Is.Not.Null) Assert.That(json, Is.Not.Empty) Assert.That(json|> MarshallingData.Sanitize, - Is.EqualTo MarshallingData.SignedSaiTransactionExampleInJson) + Is.EqualTo MarshallingData.SignedDaiTransactionExampleInJson) diff --git a/src/GWallet.Backend.Tests/data/signedAndFormattedBtcTransaction.json b/src/GWallet.Backend.Tests/data/signedAndFormattedBtcTransaction.json index d9ad44b3a..e74a38405 100644 --- a/src/GWallet.Backend.Tests/data/signedAndFormattedBtcTransaction.json +++ b/src/GWallet.Backend.Tests/data/signedAndFormattedBtcTransaction.json @@ -1,66 +1,13 @@ { "Version": "{version}", - "TypeName": "GWallet.Backend.SignedTransaction`1[[GWallet.Backend.UtxoCoin.TransactionMetadata, GWallet.Backend, Version={version}, Culture=neutral, PublicKeyToken=null]]", + "TypeName": "GWallet.Backend.SignedTransaction", "Value": { - "TransactionInfo": { - "Proposal": { - "OriginAddress": "16pKBjGGZkUXo1afyBNf5ttFvV9hauS1kR", - "Amount": { - "ValueToSend": 10.01, - "BalanceAtTheMomentOfSending": 12.02, - "Currency": { - "Case": "BTC" - } - }, - "DestinationAddress": "13jxHQDxGto46QhjFiMb78dZdys9ZD8vW5" - }, - "Metadata": { - "Fee": { - "EstimatedFeeInSatoshis": 10, - "EstimationTime": "2018-06-14T16:50:09.133411Z", - "Currency": { - "Case": "BTC" - } - }, - "Inputs": [ - { - "TransactionHash": "4d129e98d87fab00a99ebc88688752b588ec7d38c2ba5dc86d3563a6bc4c691f", - "OutputIndex": 1, - "ValueInSatoshis": 1000, - "DestinationInHex": "a9145131075257d8b8de8298e7c52891eb4b87823b9387" - } - ] - }, - "Cache": { - "UsdPrice": { - "BTC": 9156.19, - "ETC": 19.8644, - "ETH": 691.52, - "LTC": 173.592, - "SAI": 1.00376 - }, - "Addresses": { - "0xba766d6d13E2Cc921Bf6e896319D32502af9e37E": [ - "ETH", - "SAI", - "ETC" - ], - "3Buz1evVsQeHtDfQAmwfAKQsUzAt3f4TuR": [ - "BTC" - ], - "MJ88KYLTpXVigiwJGevzyxfGogmKx7WiWm": [ - "LTC" - ] - }, - "Balances": { - "BTC": 0.0, - "ETC": 8.0, - "ETH": 7.08, - "LTC": 0.0, - "SAI": 1.0 - } - } + "FeeCurrency": { + "Case": "BTC" }, - "RawTransaction": "0200000000010111b6e0460bb810b05744f8d38262f95fbab02b168b070598a6f31fad438fced4000000001716001427c106013c0042da165c082b3870c31fb3ab4683feffffff0200ca9a3b0000000017a914d8b6fcc85a383261df05423ddf068a8987bf0287873067a3fa0100000017a914d5df0b9ca6c0e1ba60a9ff29359d2600d9c6659d870247304402203b85cb05b43cc68df72e2e54c6cb508aa324a5de0c53f1bbfe997cbd7509774d022041e1b1823bdaddcd6581d7cde6e6a4c4dbef483e42e59e04dbacbaf537c3e3e8012103fbbdb3b3fc3abbbd983b20a557445fb041d6f21cc5977d2121971cb1ce5298978c000000" + "Currency": { + "Case": "BTC" + }, + "RawTransaction": "01000000000102cd9e4c06746721fe5d0ecdeabe29a0f05cc22bd7013ff76132efe476d9346bdc0000000017160014618869483590d6c1afe51160f244982e055d213ffdffffffef2763e4690975dc9415d36c06361ddee8393e6d9d86edd748ca21f10788fbc30100000017160014618869483590d6c1afe51160f244982e055d213ffdffffff01ba89000000000000220020574712746ca1942b8f0e3d52e4c1fd9406c3e1b602b328a2a77a57c233fed4640247304402206e9359074007c597a8243d4e5bbfb18ccfd83c0206fcbd1fafc02eb4946852f90220566e0d719b48d11f193d5d6d80eccbaaf44ee1771bf9ea7fd3810d41c5cb429f012102b7326aff8f2e56a341c31fbf50d0ce1a641859d837daffd7bf03f1f80a8c5eaa0247304402202fdbb2ea123c1150b26835ecd54cd59a22bca6a47f32167b35f355fbfcc12d22022011b8314e51b229d6d5a5ee216c9e038b5e05d1b5123485b935a1f823f2bf2279012102b7326aff8f2e56a341c31fbf50d0ce1a641859d837daffd7bf03f1f80a8c5eaa00000000" } } diff --git a/src/GWallet.Backend.Tests/data/signedAndFormattedDaiTransaction.json b/src/GWallet.Backend.Tests/data/signedAndFormattedDaiTransaction.json new file mode 100644 index 000000000..cf73e51dc --- /dev/null +++ b/src/GWallet.Backend.Tests/data/signedAndFormattedDaiTransaction.json @@ -0,0 +1,13 @@ +{ + "Version": "{version}", + "TypeName": "GWallet.Backend.SignedTransaction", + "Value": { + "FeeCurrency": { + "Case": "ETH" + }, + "Currency": { + "Case": "DAI" + }, + "RawTransaction": "f8a90185016c653675828792946b175474e89094c44da98b954eedeac495271d0f80b844a9059cbb000000000000000000000000d2fdfa29d5ccbb8168ba248d59ded7a25396f84e0000000000000000000000000000000000000000000000000de0b6b3a764000026a0d5c49133f38f3b60aa41747a4b7cc300a6dac87803b82ba23af9a97fd5994c3ea03122864fd6b294a3da2f3827e70fa861838a168f6533e03587358a6bdc594235" + } +} diff --git a/src/GWallet.Backend.Tests/data/signedAndFormattedEtherTransaction.json b/src/GWallet.Backend.Tests/data/signedAndFormattedEtherTransaction.json index 401148db1..cde673821 100644 --- a/src/GWallet.Backend.Tests/data/signedAndFormattedEtherTransaction.json +++ b/src/GWallet.Backend.Tests/data/signedAndFormattedEtherTransaction.json @@ -1,49 +1,13 @@ { "Version": "{version}", - "TypeName": "GWallet.Backend.SignedTransaction`1[[GWallet.Backend.Ether.TransactionMetadata, GWallet.Backend, Version={version}, Culture=neutral, PublicKeyToken=null]]", + "TypeName": "GWallet.Backend.SignedTransaction", "Value": { - "TransactionInfo": { - "Proposal": { - "OriginAddress": "0xf3j4m0rjx94sushh03j", - "Amount": { - "ValueToSend": 10.01, - "BalanceAtTheMomentOfSending": 12.02, - "Currency": { - "Case": "ETC" - } - }, - "DestinationAddress": "0xf3j4m0rjxdddud9403j" - }, - "Metadata": { - "Fee": { - "GasLimit": 21000, - "GasPriceInWei": 6969, - "Currency": { - "Case": "ETC" - }, - "EstimationTime": "2018-06-14T16:50:09.133411Z" - }, - "TransactionCount": 69 - }, - "Cache": { - "UsdPrice": { - "ETC": 169.99999999, - "ETH": 161.796 - }, - "Addresses": { - "0xFOOBARBAZ": [ - "ETC" - ], - "1fooBarBaz": [ - "BTC" - ] - }, - "Balances": { - "BTC": 0.0, - "ETC": 123456789.12345678 - } - } + "FeeCurrency": { + "Case": "ETH" }, - "RawTransaction": "doijfsoifjdosisdjfomirmjosmi" + "Currency": { + "Case": "ETH" + }, + "RawTransaction": "f86b0185019d334a3482520894d2fdfa29d5ccbb8168ba248d59ded7a25396f84e87022a8ad81f98768026a06bb7c1f8f2b40ed2bc3a3b572cdde7fddb42a8d43c561c60580183b0ed8c2d9fa035183359feab8789642135a253371f80781f4a870f0cae8a7368c5d7e102a688" } } diff --git a/src/GWallet.Backend.Tests/data/signedAndFormattedSaiTransaction.json b/src/GWallet.Backend.Tests/data/signedAndFormattedSaiTransaction.json deleted file mode 100644 index 0dd6bfab1..000000000 --- a/src/GWallet.Backend.Tests/data/signedAndFormattedSaiTransaction.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "Version": "{version}", - "TypeName": "GWallet.Backend.SignedTransaction`1[[GWallet.Backend.Ether.TransactionMetadata, GWallet.Backend, Version={version}, Culture=neutral, PublicKeyToken=null]]", - "Value": { - "TransactionInfo": { - "Proposal": { - "OriginAddress": "0xba766d6d13E2Cc921Bf6e896319D32502af9e37E", - "Amount": { - "ValueToSend": 1.0, - "BalanceAtTheMomentOfSending": 7.08, - "Currency": { - "Case": "SAI" - } - }, - "DestinationAddress": "0xDb0381B1a380d8db2724A9Ca2d33E0C6C044bE3b" - }, - "Metadata": { - "Fee": { - "GasLimit": 37298, - "GasPriceInWei": 3343750000, - "Currency": { - "Case": "ETH" - }, - "EstimationTime": "2018-06-14T16:50:09.133411Z" - }, - "TransactionCount": 7 - }, - "Cache": { - "UsdPrice": { - "BTC": 9156.19, - "ETC": 19.8644, - "ETH": 691.52, - "LTC": 173.592, - "SAI": 1.00376 - }, - "Addresses": { - "0xba766d6d13E2Cc921Bf6e896319D32502af9e37E": [ - "ETH", - "SAI", - "ETC" - ], - "3Buz1evVsQeHtDfQAmwfAKQsUzAt3f4TuR": [ - "BTC" - ], - "MJ88KYLTpXVigiwJGevzyxfGogmKx7WiWm": [ - "LTC" - ] - }, - "Balances": { - "BTC": 0.0, - "ETC": 8.0, - "ETH": 7.08, - "LTC": 0.0, - "SAI": 1.0 - } - } - }, - "RawTransaction": "f8a80784c74d93708291b29489d24a6b4ccb1b6faa2625fe562bdd9a2326035980b844a9059cbb000000000000000000000000db0381b1a380d8db2724a9ca2d33e0c6c044be3b0000000000000000000000000000000000000000000000000de0b6b3a764000026a072cdeb03affd5977c76366efbc1405fbb4fa997ce72c1e4554ba9ec5ef772ddca069d522ea304efebd2537330870bc1ca9e9a6fe3eb5f8d8f66c1b82d9fc27a4bf" - } -} diff --git a/src/GWallet.Backend/Account.fs b/src/GWallet.Backend/Account.fs index a2b006f1a..e53216d25 100644 --- a/src/GWallet.Backend/Account.fs +++ b/src/GWallet.Backend/Account.fs @@ -229,13 +229,32 @@ module Account = | _ -> () } + + let GetTransactionProposal (signedTransaction: SignedTransaction) = + if signedTransaction.Currency.IsUtxo() then + UtxoCoin.Account.GetSignedTransactionProposal signedTransaction + elif signedTransaction.Currency.IsEtherBased() then + Ether.Account.GetSignedTransactionProposal signedTransaction + else + failwith "Unknown currency type for parsing proposal from raw transaction" + + let GetTransactionMetadata (signedTransaction: SignedTransaction) = + if signedTransaction.Currency.IsUtxo() then + UtxoCoin.Account.GetTransactionFeeMetadata signedTransaction + elif signedTransaction.Currency.IsEtherBased() then + async { + return Ether.Account.GetTransactionFeeMetadata signedTransaction + } + else + failwith "Unknown currency type for parsing metadata from raw transaction" + // FIXME: broadcasting shouldn't just get N consistent replies from FaultTolerantClient, // but send it to as many as possible, otherwise it could happen that some server doesn't // broadcast it even if you sent it - let BroadcastTransaction (trans: SignedTransaction<_>) (ignoreHigherMinerFeeThanAmount: bool): Async = + let BroadcastTransaction (trans: SignedTransaction) (ignoreHigherMinerFeeThanAmount: bool): Async = async { - let currency = trans.TransactionInfo.Proposal.Amount.Currency + let currency = trans.Currency let! txId = if currency.IsEtherBased() then @@ -245,9 +264,11 @@ module Account = else failwith <| SPrintF1 "Unknown currency %A" currency - do! CheckIfOutOfGas trans.TransactionInfo.Metadata txId + let! txMetadata = GetTransactionMetadata trans + + do! CheckIfOutOfGas txMetadata txId - SaveOutgoingTransactionInCache trans.TransactionInfo.Proposal trans.TransactionInfo.Metadata txId + SaveOutgoingTransactionInCache (GetTransactionProposal trans) txMetadata txId let uri = BlockExplorer.GetTransaction currency txId return uri @@ -404,7 +425,7 @@ module Account = async { do! ValidateAddress currency destination - let! txId = + let! txId, txRawTransaction = match txMetadata with | :? UtxoCoin.TransactionMetadata as btcTxMetadata -> if not (currency.IsUtxo()) then @@ -423,6 +444,15 @@ module Account = | _ -> failwith "Unknown tx metadata type" + let signedTransaction = + { + SignedTransaction.FeeCurrency = txMetadata.Currency + Currency = currency + RawTransaction = txRawTransaction + } + + let! txMetadata = GetTransactionMetadata signedTransaction + do! CheckIfOutOfGas txMetadata txId let transactionProposal = @@ -447,40 +477,19 @@ module Account = unsignedTrans.Metadata password - { TransactionInfo = unsignedTrans; RawTransaction = rawTransaction } + { + FeeCurrency = unsignedTrans.Metadata.Currency + Currency = unsignedTrans.Proposal.Amount.Currency + RawTransaction = rawTransaction + } - let private ExportSignedTransaction (trans: SignedTransaction<_>) = + let private ExportSignedTransaction (trans: SignedTransaction) = Marshalling.Serialize trans - let private SerializeSignedTransactionPlain (trans: SignedTransaction<_>): string = - let json = - match trans.TransactionInfo.Metadata.GetType() with - | t when t = typeof -> - let unsignedEthTx = { - Metadata = box trans.TransactionInfo.Metadata :?> Ether.TransactionMetadata; - Proposal = trans.TransactionInfo.Proposal; - Cache = trans.TransactionInfo.Cache; - } - let signedEthTx = { - TransactionInfo = unsignedEthTx; - RawTransaction = trans.RawTransaction; - } - ExportSignedTransaction signedEthTx - | t when t = typeof -> - let unsignedBtcTx = { - Metadata = box trans.TransactionInfo.Metadata :?> UtxoCoin.TransactionMetadata; - Proposal = trans.TransactionInfo.Proposal; - Cache = trans.TransactionInfo.Cache; - } - let signedBtcTx = { - TransactionInfo = unsignedBtcTx; - RawTransaction = trans.RawTransaction; - } - ExportSignedTransaction signedBtcTx - | _ -> failwith "Unknown miner fee type" - json + let private SerializeSignedTransactionPlain (trans: SignedTransaction): string = + ExportSignedTransaction trans - let SerializeSignedTransaction (transaction: SignedTransaction<_>) + let SerializeSignedTransaction (transaction: SignedTransaction) (compressed: bool) : string = @@ -490,7 +499,7 @@ module Account = else Marshalling.Compress json - let SaveSignedTransaction (trans: SignedTransaction<_>) (filePath: string) = + let SaveSignedTransaction (trans: SignedTransaction) (filePath: string) = let json = SerializeSignedTransaction trans false File.WriteAllText(filePath, json) @@ -696,12 +705,12 @@ module Account = let deserializedBtcTransaction: UnsignedTransaction = Marshalling.Deserialize json deserializedBtcTransaction.ToAbstract() - | _ when transType.GetGenericTypeDefinition() = typedefof> -> + | _ when transType.GetGenericTypeDefinition() = typedefof -> raise TransactionAlreadySigned | unexpectedType -> raise <| Exception(SPrintF1 "Unknown unsignedTransaction subtype: %s" unexpectedType.FullName) - let public ImportSignedTransactionFromJson (jsonOrCompressedJson: string): SignedTransaction = + let public ImportSignedTransactionFromJson (jsonOrCompressedJson: string): SignedTransaction = let json = try @@ -713,14 +722,8 @@ module Account = let transType = Marshalling.ExtractType json match transType with - | _ when transType = typeof> -> - let deserializedBtcTransaction: SignedTransaction = - Marshalling.Deserialize json - deserializedBtcTransaction.ToAbstract() - | _ when transType = typeof> -> - let deserializedBtcTransaction: SignedTransaction = - Marshalling.Deserialize json - deserializedBtcTransaction.ToAbstract() + | _ when transType = typeof -> + Marshalling.Deserialize json | _ when transType.GetGenericTypeDefinition() = typedefof> -> raise TransactionNotSignedYet | unexpectedType -> @@ -746,14 +749,9 @@ module Account = let deserializedTransaction: UnsignedTransaction = Marshalling.Deserialize json Unsigned(deserializedTransaction.ToAbstract()) - | _ when transType = typeof> -> - let deserializedTransaction: SignedTransaction = - Marshalling.Deserialize json - Signed(deserializedTransaction.ToAbstract()) - | _ when transType = typeof> -> - let deserializedTransaction: SignedTransaction = - Marshalling.Deserialize json - Signed(deserializedTransaction.ToAbstract()) + | _ when transType = typeof -> + Marshalling.Deserialize json + |> Signed | unexpectedType -> failwith <| SPrintF1 "Unknown unsignedTransaction subtype: %s" unexpectedType.FullName @@ -768,16 +766,14 @@ module Account = ImportUnsignedTransactionFromJson unsignedTransInJson - let GetSignedTransactionDetails<'T when 'T :> IBlockchainFeeInfo> (signedTransaction: SignedTransaction<'T>) + let GetSignedTransactionDetails (signedTransaction: SignedTransaction) : ITransactionDetails = - let currency = signedTransaction.TransactionInfo.Proposal.Amount.Currency + let currency = signedTransaction.Currency if currency.IsUtxo () then UtxoCoin.Account.GetSignedTransactionDetails - signedTransaction.RawTransaction - currency + signedTransaction elif currency.IsEtherBased () then Ether.Account.GetSignedTransactionDetails signedTransaction else failwith <| (SPrintF1 "Unknown currency: %A" currency) - diff --git a/src/GWallet.Backend/Ether/EtherAccount.fs b/src/GWallet.Backend/Ether/EtherAccount.fs index b9b26e355..b7d75353e 100644 --- a/src/GWallet.Backend/Ether/EtherAccount.fs +++ b/src/GWallet.Backend/Ether/EtherAccount.fs @@ -255,9 +255,9 @@ module internal Account = ValidateMinerFee trans Ether.Server.BroadcastTransaction currency ("0x" + trans) - let BroadcastTransaction (trans: SignedTransaction<_>) = + let BroadcastTransaction (trans: SignedTransaction) = BroadcastRawTransaction - trans.TransactionInfo.Proposal.Amount.Currency + trans.Currency trans.RawTransaction let internal GetPrivateKey (account: NormalAccount) password = @@ -401,15 +401,19 @@ module internal Account = (amount: TransferAmount) (password: string) (ignoreHigherMinerFeeThanAmount: bool) = - let baseAccount = account :> IAccount - if (baseAccount.PublicAddress.Equals(destination, StringComparison.InvariantCultureIgnoreCase)) then - raise DestinationEqualToOrigin + async { + let baseAccount = account :> IAccount + if (baseAccount.PublicAddress.Equals(destination, StringComparison.InvariantCultureIgnoreCase)) then + raise DestinationEqualToOrigin + + let currency = baseAccount.Currency - let currency = baseAccount.Currency + let trans = SignTransaction account txMetadata destination amount password - let trans = SignTransaction account txMetadata destination amount password + let! txId = BroadcastRawTransaction currency trans ignoreHigherMinerFeeThanAmount - BroadcastRawTransaction currency trans ignoreHigherMinerFeeThanAmount + return txId, trans + } let private CreateInternal (password: string) (seed: array): FileRepresentation = let privateKey = EthECKey(seed, true) @@ -449,42 +453,43 @@ module internal Account = } ExportUnsignedTransactionToJson unsignedTransaction + let GetTransactionFeeMetadata (signedTransaction: SignedTransaction): IBlockchainFeeInfo = + let intDecoder = IntTypeDecoder() + let parsedTx = TransactionFactory.CreateTransaction signedTransaction.RawTransaction :?> SignedLegacyTransaction + let gasLimitInWei = intDecoder.DecodeBigInteger parsedTx.GasLimit |> int64 + let gasPriceInWei = intDecoder.DecodeBigInteger parsedTx.GasPrice |> int64 + let nonce = intDecoder.DecodeBigInteger parsedTx.Nonce |> int64 - let GetSignedTransactionDetails (signedTransaction: SignedTransaction<'T>): ITransactionDetails = - - match signedTransaction.TransactionInfo.Proposal.Amount.Currency with - | SAI | DAI -> - // FIXME: derive the transaction details from the raw transaction so that we can remove the proposal from - // the SignedTransaction type (as it's redundant); and when we remove it, we can also rename - // IBlockchainFeeInfo's Currency to "FeeCurrency", or change "Metadata" members whose type is - // IBlockchainFeeInfo to have "fee" in the name too, otherwise is to easy to use ETH instead of DAI - signedTransaction.TransactionInfo.Proposal :> ITransactionDetails - - | _ -> - let getTransactionChainId (tx: SignedLegacyTransactionBase) = - // the chain id can be deconstructed like so - - // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md - // into one of the following - - // https://chainid.network/ - // NOTE: according to the SO discussion, the following alrogithm is adequate - - // https://stackoverflow.com/questions/68023440/how-do-i-use-nethereum-to-extract-chain-id-from-a-raw-transaction - let v = IntTypeDecoder().DecodeBigInteger tx.Signature.V - let chainId = (v - BigInteger 35) / BigInteger 2 - chainId - - let getTransactionCurrency (tx: SignedLegacyTransactionBase) = - match int (getTransactionChainId tx) with - | chainId when chainId = int Config.EthNet -> ETH - | chainId when chainId = int Config.EtcNet -> ETC - | other -> failwith <| SPrintF1 "Could not infer currency from transaction where chainId = %i." other - - let tx = TransactionFactory.CreateTransaction signedTransaction.RawTransaction :?> SignedLegacyTransaction - - // HACK: I prefix 12 elements to the address due to AddressTypeDecoder expecting some sort of header... - let address = AddressTypeDecoder().Decode (Array.append (Array.zeroCreate 12) tx.ReceiveAddress) - - let destAddress = address.ConvertToEthereumChecksumAddress() - + { + TransactionMetadata.Fee = + MinerFee(gasLimitInWei, gasPriceInWei, DateTime.Now, signedTransaction.FeeCurrency) + TransactionCount = nonce + } :> IBlockchainFeeInfo + + let GetSignedTransactionDetails (signedTransaction: SignedTransaction): ITransactionDetails = + let getTransactionChainId (tx: SignedLegacyTransactionBase) = + // the chain id can be deconstructed like so - + // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md + // into one of the following - + // https://chainid.network/ + // NOTE: according to the SO discussion, the following alrogithm is adequate - + // https://stackoverflow.com/questions/68023440/how-do-i-use-nethereum-to-extract-chain-id-from-a-raw-transaction + let v = IntTypeDecoder().DecodeBigInteger tx.Signature.V + let chainId = (v - BigInteger 35) / BigInteger 2 + chainId + + let getTransactionCurrency (tx: SignedLegacyTransactionBase) = + match int (getTransactionChainId tx) with + | chainId when chainId = int Config.EthNet -> ETH + | chainId when chainId = int Config.EtcNet -> ETC + | other -> failwith <| SPrintF1 "Could not infer currency from transaction where chainId = %i." other + + let tx = TransactionFactory.CreateTransaction signedTransaction.RawTransaction :?> SignedLegacyTransaction + + let destAddress = tx.ReceiveAddress.ConvertToEthereumChecksumAddress() + + match TokenManager.TryGetCurrencyByContractAddress destAddress with + | None -> let txDetails = { OriginAddress = TransactionVerificationAndRecovery.GetSenderAddress signedTransaction.RawTransaction @@ -493,3 +498,26 @@ module internal Account = DestinationAddress = destAddress } txDetails :> ITransactionDetails + | Some tokenCurrency -> + let tokenServiceWrapper = + TokenManager.OfflineTokenServiceWrapper tokenCurrency + + let destinationAddress, amountInWei = + tokenServiceWrapper.DecodeInputDataForTransferTransaction tx.Data + + let txDetails = + { + OriginAddress = TransactionVerificationAndRecovery.GetSenderAddress signedTransaction.RawTransaction + Amount = UnitConversion.Convert.FromWei amountInWei + Currency = tokenCurrency + DestinationAddress = destinationAddress + } + txDetails :> ITransactionDetails + let GetSignedTransactionProposal (signedTx: SignedTransaction): UnsignedTransactionProposal = + let txDetail = GetSignedTransactionDetails signedTx + { + UnsignedTransactionProposal.Amount = + TransferAmount(txDetail.Amount, txDetail.Amount, txDetail.Currency) + OriginAddress = txDetail.OriginAddress + DestinationAddress = txDetail.DestinationAddress + } \ No newline at end of file diff --git a/src/GWallet.Backend/Ether/TokenManager.fs b/src/GWallet.Backend/Ether/TokenManager.fs index 015c0b036..c627f5157 100644 --- a/src/GWallet.Backend/Ether/TokenManager.fs +++ b/src/GWallet.Backend/Ether/TokenManager.fs @@ -4,6 +4,7 @@ open System.Numerics open Nethereum.Web3 open Nethereum.Hex.HexTypes +open Nethereum.Hex.HexConvertors.Extensions open Nethereum.StandardTokenEIP20 open Nethereum.StandardTokenEIP20.ContractDefinition @@ -12,10 +13,20 @@ open GWallet.Backend.FSharpUtil.UwpHacks module TokenManager = + let ContractAddresses: Map = + Map [ + Currency.DAI, "0x6B175474E89094C44Da98b954EedeAC495271d0F" + Currency.SAI, "0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359" + ] + + let TryGetCurrencyByContractAddress addr = + ContractAddresses + |> Map.tryFindKey (fun _currency contractAddress -> contractAddress = addr) + let GetTokenContractAddress currency = match currency with - | Currency.DAI -> "0x6B175474E89094C44Da98b954EedeAC495271d0F" - | Currency.SAI -> "0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359" + | Currency.DAI + | Currency.SAI -> ContractAddresses.[currency] | _ -> raise <| invalidOp (SPrintF1 "%A has no contract address" currency) type TokenServiceWrapper(web3, currency: Currency) = @@ -45,6 +56,26 @@ module TokenManager = failwith "Assertion failed: transactionInput's VALUE property should be equal to passed tokenAmountInWei parameter" transactionInput.Data + member self.DecodeInputDataForTransferTransaction (data: byte[]) = + let transferFuncBuilder = self.ContractHandler.GetFunction() + let decodedInput = transferFuncBuilder.DecodeInput (data.ToHex true) + + let expectedParamsCount = 2 + + let transferDestination, transferAmountInWei = + try + if decodedInput.Count = expectedParamsCount then + decodedInput.[0].Result :?> string, + decodedInput.[1].Result :?> BigInteger + else + failwith <| SPrintF2 "Invalid transfer function parameters count, expected %i got %i" expectedParamsCount decodedInput.Count + with + | :? System.InvalidCastException -> + failwith "Invalid transfer function parameters type" + + transferDestination, transferAmountInWei + + // this is a dummy instance we need in order to pass it to base class of StandardTokenService, but not // really used online; FIXME: propose "Web3-less" overload to Nethereum let private dummyOfflineWeb3 = Web3() diff --git a/src/GWallet.Backend/Transaction.fs b/src/GWallet.Backend/Transaction.fs index 6f1764e69..b20670a83 100644 --- a/src/GWallet.Backend/Transaction.fs +++ b/src/GWallet.Backend/Transaction.fs @@ -46,17 +46,13 @@ type UnsignedTransaction<'T when 'T:> IBlockchainFeeInfo> = Proposal = self.Proposal; } -type SignedTransaction<'T when 'T:> IBlockchainFeeInfo> = +type SignedTransaction = { - TransactionInfo: UnsignedTransaction<'T>; - RawTransaction: string; + FeeCurrency: Currency + Currency: Currency + RawTransaction: string } - member self.ToAbstract(): SignedTransaction = - { - TransactionInfo = self.TransactionInfo.ToAbstract(); - RawTransaction = self.RawTransaction; - } type ImportedTransaction<'T when 'T:> IBlockchainFeeInfo> = | Unsigned of UnsignedTransaction<'T> -| Signed of SignedTransaction<'T> +| Signed of SignedTransaction diff --git a/src/GWallet.Backend/UtxoCoin/UtxoCoinAccount.fs b/src/GWallet.Backend/UtxoCoin/UtxoCoinAccount.fs index 56cf8a76a..9d2c513f1 100644 --- a/src/GWallet.Backend/UtxoCoin/UtxoCoinAccount.fs +++ b/src/GWallet.Backend/UtxoCoin/UtxoCoinAccount.fs @@ -467,7 +467,7 @@ module Account = return! Server.Query currency QuerySettings.Broadcast job None } - let internal BroadcastTransaction currency (transaction: SignedTransaction<_>) = + let internal BroadcastTransaction currency (transaction: SignedTransaction) = // FIXME: stop embedding TransactionInfo element in SignedTransaction // and show the info from the RawTx, using NBitcoin to extract it BroadcastRawTransaction currency transaction.RawTransaction @@ -477,14 +477,17 @@ module Account = (destination: string) (amount: TransferAmount) (password: string) - (ignoreHigherMinerFeeThanAmount: bool) - = - let baseAccount = account :> IAccount - if (baseAccount.PublicAddress.Equals(destination, StringComparison.InvariantCultureIgnoreCase)) then - raise DestinationEqualToOrigin - - let finalTransaction = SignTransaction account txMetadata destination amount password - BroadcastRawTransaction baseAccount.Currency finalTransaction ignoreHigherMinerFeeThanAmount + (ignoreHigherMinerFeeThanAmount: bool) = + async { + let baseAccount = account :> IAccount + if (baseAccount.PublicAddress.Equals(destination, StringComparison.InvariantCultureIgnoreCase)) then + raise DestinationEqualToOrigin + + let finalTransaction = SignTransaction account txMetadata destination amount password + let! txId = BroadcastRawTransaction baseAccount.Currency finalTransaction ignoreHigherMinerFeeThanAmount + + return txId, finalTransaction + } // TODO: maybe move this func to Backend.Account module, or simply inline it (simple enough) let public ExportUnsignedTransactionToJson trans = @@ -633,12 +636,58 @@ module Account = // TODO: propose to NBitcoin upstream to generate an NBitcoin exception instead | :? FormatException -> raise (AddressWithInvalidChecksum None) + + let GetTransactionFeeMetadata (signedTx: SignedTransaction): Async = + async { + let network = GetNetwork signedTx.Currency + let txToValidate = Transaction.Parse (signedTx.RawTransaction, network) - let GetSignedTransactionDetails<'T when 'T :> IBlockchainFeeInfo>(rawTransaction: string) - (currency: Currency) - : ITransactionDetails = - let network = GetNetwork currency - match Transaction.TryParse(rawTransaction, network) with + let totalOutputsAmount = txToValidate.TotalOut + + let getInputDetails (input: TxIn) = + async { + let job = ElectrumClient.GetBlockchainTransaction (input.PrevOut.Hash.ToString()) + let! inputOriginTxString = Server.Query signedTx.Currency (QuerySettings.Default ServerSelectionMode.Fast) job None + let inputOriginTx = Transaction.Parse (inputOriginTxString, network) + return + input.PrevOut.N, + inputOriginTx.Outputs.[input.PrevOut.N], + inputOriginTx.GetHash().ToString() + } + + let! inputs = + txToValidate.Inputs + |> Seq.map getInputDetails + |> Async.Parallel + + let totalInputsAmount = + inputs + |> Seq.sumBy (fun (_outputIndex, txOut, _transactionHash) -> txOut.Value) + + let minerFee = totalInputsAmount - totalOutputsAmount + + return + { + TransactionMetadata.Fee = + MinerFee(minerFee.Satoshi, DateTime.Now, signedTx.FeeCurrency) + // We don't need inputs since the metadata object gets casted to IBlockchainFeeInfo + Inputs = + inputs + |> Seq.map(fun (outputIndex, txOut, transactionHash) -> + { + TransactionHash = transactionHash + OutputIndex = int outputIndex + ValueInSatoshis = txOut.Value.Satoshi + DestinationInHex = txOut.ScriptPubKey.ToHex() + } + ) + |> Seq.toList + } :> IBlockchainFeeInfo + } + + let GetSignedTransactionDetails (signedTx: SignedTransaction) : ITransactionDetails = + let network = GetNetwork signedTx.Currency + match Transaction.TryParse(signedTx.RawTransaction, network) with | false, _ -> failwith "malformed transaction" | true, transaction -> @@ -667,10 +716,10 @@ module Account = let account = let accountOpt = - Config.GetAccountFiles [currency] AccountKind.ReadOnly + Config.GetAccountFiles [signedTx.Currency] AccountKind.ReadOnly |> Seq.map (fun accountFile -> - GetAccountFromFile accountFile currency AccountKind.ReadOnly + GetAccountFromFile accountFile signedTx.Currency AccountKind.ReadOnly :?> ReadOnlyUtxoAccount ) |> Seq.filter matchOriginToAccount @@ -703,6 +752,14 @@ module Account = OriginAddress = originAddress.ToString() DestinationAddress = destinationAddress.ToString() Amount = value.ToDecimal MoneyUnit.BTC - Currency = currency + Currency = signedTx.Currency } :> ITransactionDetails + let GetSignedTransactionProposal (signedTx: SignedTransaction): UnsignedTransactionProposal = + let txDetail = GetSignedTransactionDetails signedTx + { + UnsignedTransactionProposal.Amount = + TransferAmount(txDetail.Amount, txDetail.Amount + 1m, txDetail.Currency) + OriginAddress = txDetail.OriginAddress + DestinationAddress = txDetail.DestinationAddress + } \ No newline at end of file diff --git a/src/GWallet.Frontend.Console/Program.fs b/src/GWallet.Frontend.Console/Program.fs index e72719238..f2c6b65c7 100644 --- a/src/GWallet.Frontend.Console/Program.fs +++ b/src/GWallet.Frontend.Console/Program.fs @@ -80,9 +80,14 @@ let BroadcastPayment() = | Some signedTransaction -> let transactionDetails = Account.GetSignedTransactionDetails signedTransaction + let transactionMetadata = + signedTransaction + |> Account.GetTransactionMetadata + |> Async.RunSynchronously + Presentation.ShowTransactionData transactionDetails - signedTransaction.TransactionInfo.Metadata + transactionMetadata if UserInteraction.AskYesNo "Do you accept?" then try diff --git a/src/GWallet.Frontend.XF/SendPage.xaml.fs b/src/GWallet.Frontend.XF/SendPage.xaml.fs index fbdc062cf..6ac9a6da4 100644 --- a/src/GWallet.Frontend.XF/SendPage.xaml.fs +++ b/src/GWallet.Frontend.XF/SendPage.xaml.fs @@ -25,7 +25,7 @@ type TransactionProposal<'T when 'T :> IBlockchainFeeInfo> = // cold wallet about to scan proposal from hot wallet: | ColdStorageMode of Option> // hot wallet about to broadcast transaction of ReadOnly account: - | ColdStorageRemoteControl of Option> + | ColdStorageRemoteControl of Option type SendPage(account: IAccount, receivePage: Page, newReceivePageFunc: unit->Page) as self = inherit ContentPage() @@ -439,15 +439,16 @@ type SendPage(account: IAccount, receivePage: Page, newReceivePageFunc: unit->Pa passwordEntry.Focus() |> ignore ) | Some (Signed signedTransaction) -> - if account.Currency <> signedTransaction.TransactionInfo.Proposal.Amount.Currency then + let proposal = Account.GetTransactionProposal signedTransaction + if account.Currency <> proposal.Amount.Currency then MainThread.BeginInvokeOnMainThread(fun _ -> transactionEntry.TextColor <- Color.Red let err = SPrintF2 "Transaction's currency (%A) doesn't match with this currency's account (%A)" - signedTransaction.TransactionInfo.Proposal.Amount.Currency account.Currency + proposal.Amount.Currency account.Currency self.DisplayAlert("Alert", err, "OK") |> FrontendHelpers.DoubleCheckCompletionNonGeneric ) - elif account.PublicAddress <> signedTransaction.TransactionInfo.Proposal.OriginAddress then + elif account.PublicAddress <> proposal.OriginAddress then MainThread.BeginInvokeOnMainThread(fun _ -> transactionEntry.TextColor <- Color.Red let err = "Transaction's sender address doesn't match with this currency's account" @@ -612,7 +613,12 @@ type SendPage(account: IAccount, receivePage: Page, newReceivePageFunc: unit->Pa match maybeRawTransaction with | None -> () | Some rawTransaction -> - let signedTransaction = { TransactionInfo = unsignedTransaction; RawTransaction = rawTransaction } + let signedTransaction = + { + Currency = unsignedTransaction.Proposal.Amount.Currency + FeeCurrency = unsignedTransaction.Metadata.Currency + RawTransaction = rawTransaction + } let compressedTransaction = Account.SerializeSignedTransaction signedTransaction true let pairSignedTransactionPage () = PairingFromPage(self, "Copy signed transaction to the clipboard", compressedTransaction, None)