@@ -9,6 +9,18 @@ open GWallet.Backend.FSharpUtil.UwpHacks
99
1010
1111module BtcTransactionPrinting =
12+ type private ProcessedHistoryEntry =
13+ {
14+ Date: DateTime
15+ Outputs: NBitcoin .TxOutList
16+ }
17+
18+ type private EntryWithSharedAddress =
19+ {
20+ Date: DateTime
21+ SharedOutputs: seq < NBitcoin .TxOut >
22+ }
23+
1224 let GetBitcoinPriceForDate ( date : DateTime ) : Async < Result < decimal , Exception >> =
1325 async {
1426 try
@@ -26,7 +38,8 @@ module BtcTransactionPrinting =
2638 return Error ex
2739 }
2840
29- let PrintTransactions ( maxTransactionsCount : uint32 ) ( btcAddress : string ) =
41+ let PrintTransactions ( maxTransactionsCountOption : uint32 option ) ( btcAddress : string ) =
42+ let maxTransactionsCount = defaultArg maxTransactionsCountOption UInt32.MaxValue
3043 let address = NBitcoin.BitcoinAddress.Create( btcAddress, NBitcoin.Network.Main)
3144 async {
3245 let scriptHash = Account.GetElectrumScriptHashFromPublicAddress Currency.BTC btcAddress
@@ -70,13 +83,82 @@ module BtcTransactionPrinting =
7083 Console.WriteLine( " Could not get bitcoin price for the date. An error has occured:\n " + exn.ToString())
7184 Console.WriteLine( SPrintF1 " date: %A UTC" dateTime)
7285 Console.WriteLine()
73- return ! processHistory rest ( maxTransactionsToPrint - 1 u)
86+ let! otherEntries = processHistory rest ( maxTransactionsToPrint - 1 u)
87+ return { Date = dateTime; Outputs = transactionInfo.Outputs } :: otherEntries
7488 else
7589 return ! processHistory rest maxTransactionsToPrint
7690 }
77- | _ -> async { return () }
91+ | _ -> async { return [] }
7892
79- do ! processHistory sortedHistory maxTransactionsCount
93+ let! processedEntries = processHistory sortedHistory maxTransactionsCount
94+
95+ if maxTransactionsCountOption.IsSome then
96+ let getAddress ( output : NBitcoin.TxOut ) =
97+ output.ScriptPubKey.GetDestinationAddress NBitcoin.Network.Main
98+
99+ let allAddressesExceptOurs =
100+ processedEntries
101+ |> Seq.collect(
102+ fun entry ->
103+ entry.Outputs
104+ |> Seq.map getAddress)
105+ |> Seq.filter ( fun each -> each <> address)
106+ |> Seq.distinct
107+ |> Seq.cache
108+
109+ let sharedAddresses =
110+ allAddressesExceptOurs
111+ |> Seq.filter (
112+ fun addr ->
113+ processedEntries
114+ |> Seq.forall(
115+ fun entry ->
116+ entry.Outputs
117+ |> Seq.exists ( fun output -> output.IsTo addr) ) )
118+ |> Seq.cache
119+
120+ let entriesWithSharedAddresses =
121+ processedEntries
122+ |> Seq.choose (
123+ fun entry ->
124+ let sharedOutputs =
125+ entry.Outputs
126+ |> Seq.filter (
127+ fun output ->
128+ sharedAddresses |> Seq.exists ( fun addr -> output.IsTo addr))
129+ if sharedOutputs |> Seq.isEmpty then
130+ None
131+ else
132+ let outputsToOurAddress = entry.Outputs |> Seq.filter ( fun output -> output.IsTo address)
133+ Some {
134+ SharedOutputs = sharedOutputs |> Seq.append outputsToOurAddress
135+ Date = entry.Date
136+ } )
137+ |> Seq.cache
138+
139+ if ( entriesWithSharedAddresses |> Seq.length) >= 2 then
140+ Console.WriteLine( SPrintF1 " Transactions with outputs shared with %A :\n " address)
141+ for entry in entriesWithSharedAddresses do
142+ let totalAmount =
143+ entry.SharedOutputs
144+ |> Seq.sumBy ( fun txOut -> txOut.Value)
145+ let sharedOutputs =
146+ entry.SharedOutputs
147+ |> Seq.groupBy getAddress
148+ let currentSharedAddresses =
149+ sharedOutputs
150+ |> Seq.map fst
151+
152+ Console.WriteLine( SPrintF1 " Transaction with outputs to %s " ( String.Join( " , " , currentSharedAddresses)))
153+ Console.WriteLine( SPrintF1 " Date: %A UTC" entry.Date)
154+ Console.WriteLine( SPrintF1 " Total BTC: %A " totalAmount)
155+ for addr, outputs in sharedOutputs do
156+ let amount = outputs |> Seq.sumBy ( fun txOut -> txOut.Value)
157+ let percentage =
158+ amount.ToDecimal( NBitcoin.MoneyUnit.BTC) / totalAmount.ToDecimal( NBitcoin.MoneyUnit.BTC) * 100.0 m
159+ Console.WriteLine( SPrintF3 " Sent %A BTC to %A (%s %%)" amount addr ( percentage.ToString( " F2" )))
160+ Console.WriteLine()
161+
80162 Console.WriteLine( " End of results" )
81163 Console.ReadKey() |> ignore
82164 return 0
0 commit comments