private static void SignTransaction(PrivateKeyAccountClient acc, Transactions.TransactionData t, string multisigAcc)
        {
            Console.WriteLine("signing transaction");
            try
            {
                acc.BeginSignatureTransactionAsync(ar => {
                    try {
                        if (ar.Content.Code == 1)
                        {
                            var sum = new TxSummary()
                            {
                                AccAddress = multisigAcc,
                                DateOfTx   = DateTime.Now,
                                Amount     = t.transaction.otherTrans.amount
                            };

                            TxSummaryController.AddSummaryForAccount(sum);
                        }
                        else
                        {
                            Console.WriteLine(ar.Content.Code);
                        }
                        Console.WriteLine(ar.Content.Message);
                        Console.WriteLine();
                        Console.WriteLine();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex);
                    }
                }, new MultisigSignatureTransactionData
                {
                    Deadline = int.Parse(ConfigurationManager.AppSettings["deadline"]) == 0
                      ? 82800 : int.Parse(ConfigurationManager.AppSettings["deadline"]),
                    TransactionHash = t.meta.data,
                    MultisigAddress = new Address(multisigAcc),
                }).AsyncWaitHandle.WaitOne();
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                SignTransaction(acc, t, multisigAcc);
            }
        }
        internal bool ScanTxAgainstRuleSet(Transactions.TransactionData t)
        {
            var multisigAccInfo = new AccountClient(Con);

            var valid = true;

            multisigAccInfo.BeginGetAccountInfoFromPublicKey(ar => {
                if (_black.Count > 0 && _black.Contains(StringUtils.GetResultsWithoutHyphen(t.transaction.otherTrans.recipient)))
                {
                    Console.WriteLine("failed on blacklist");
                    valid = false;
                }

                if (_white.Count > 0 && !_white.Contains(StringUtils.GetResultsWithoutHyphen(t.transaction.otherTrans.recipient)))
                {
                    Console.WriteLine("failed on white list");
                    valid = false;
                }


                if (long.Parse(ConfigurationManager.AppSettings["maxTx"]) != 0 && t.transaction.otherTrans.amount >= long.Parse(ConfigurationManager.AppSettings["maxTx"]) * 1000000)
                {
                    Console.WriteLine("failed max transaction size");
                    valid = false;
                }

                if (long.Parse(ConfigurationManager.AppSettings["minTx"]) != 0 && t.transaction.otherTrans.amount <= long.Parse(ConfigurationManager.AppSettings["minTx"]) * 1000000)
                {
                    Console.WriteLine("failed on min transaction size");
                    valid = false;
                }

                if (long.Parse(ConfigurationManager.AppSettings["maxBal"]) != 0 && ar.Content.Account.Balance >= long.Parse(ConfigurationManager.AppSettings["maxBal"]) * 1000000)
                {
                    Console.WriteLine("failed on max balance");
                    valid = false;
                }

                if (long.Parse(ConfigurationManager.AppSettings["minBal"]) != 0 && ar.Content.Account.Balance <= long.Parse(ConfigurationManager.AppSettings["minBal"]) * 1000000)
                {
                    Console.WriteLine("failed on min balance");
                    valid = false;
                }

                if (ConfigurationManager.AppSettings["secretCode"] != "" && t.transaction.otherTrans.message.payload != ConfigurationManager.AppSettings["secretCode"])
                {
                    Console.WriteLine("failed on secret code");
                    valid = false;
                }

                var sum1 = TxSummaryController.GetSummaryForAccount(ar.Content.Account.Address, 1);

                if (int.Parse(ConfigurationManager.AppSettings["maxDayTx"]) != 0 && sum1 != null && sum1.Count >= int.Parse(ConfigurationManager.AppSettings["maxDayTx"]))
                {
                    Console.WriteLine("failed on daily max transactions");
                    valid = false;
                }

                var sum7 = TxSummaryController.GetSummaryForAccount(ar.Content.Account.Address, 7);

                if (int.Parse(ConfigurationManager.AppSettings["maxWeekTx"]) != 0 && sum7 != null && sum7.Count >= int.Parse(ConfigurationManager.AppSettings["maxWeekTx"]))
                {
                    Console.WriteLine("failed on weekly max transactions");
                    valid = false;
                }

                var sum31 = TxSummaryController.GetSummaryForAccount(ar.Content.Account.Address, 31);

                if (int.Parse(ConfigurationManager.AppSettings["maxMonthTx"]) != 0 && sum31 != null && sum31.Count >= int.Parse(ConfigurationManager.AppSettings["maxMonthTx"]))
                {
                    Console.WriteLine("failed on monthly max transactions");
                    valid = false;
                }

                if (long.Parse(ConfigurationManager.AppSettings["maxDayAmount"]) != 0 && sum1 != null && sum1.Sum(tx => tx.Amount) >= long.Parse(ConfigurationManager.AppSettings["maxDayAmount"]) * 1000000)
                {
                    Console.WriteLine("failed on daily max transactions");
                    valid = false;
                }

                if (long.Parse(ConfigurationManager.AppSettings["maxWeekAmount"]) != 0 && sum7 != null && sum7.Sum(tx => tx.Amount) >= long.Parse(ConfigurationManager.AppSettings["maxWeekAmount"]) * 1000000)
                {
                    Console.WriteLine("failed on weekly max transactions");
                    valid = false;
                }

                if (long.Parse(ConfigurationManager.AppSettings["maxMonthAmount"]) != 0 && sum31 != null && sum31.Sum(tx => tx.Amount) >= long.Parse(ConfigurationManager.AppSettings["maxMonthAmount"]) * 1000000)
                {
                    Console.WriteLine("failed on monthly max transactions");
                    valid = false;
                }

                if (ConfigurationManager.AppSettings["ICOAccountPubKey"] != "")
                {
                    valid = false;

                    // get all incoming transactions to the ICO deposit account
                    var txs = GetTransactions(AddressEncoding.ToEncoded(Con.GetNetworkVersion(), new CSharp2nem.Model.AccountSetup.PublicKey(ConfigurationManager.AppSettings["ICOAccountPubKey"])), null);

                    if ((t.transaction.type == 257 ? t.transaction.message?.payload : t.transaction.otherTrans?.message?.payload) != null)
                    {
                        while (!txs.Exists(e => e.meta.hash.data == Encoding.UTF8.GetString(CryptoBytes.FromHexString((t.transaction.type == 257 ? t.transaction.message?.payload : t.transaction.otherTrans?.message?.payload)))))
                        {
                            var tx = GetTransactions(AddressEncoding.ToEncoded(Con.GetNetworkVersion(), new CSharp2nem.Model.AccountSetup.PublicKey(ConfigurationManager.AppSettings["ICOAccountPubKey"])), txs[txs.Count - 1].meta.hash.data);

                            txs.AddRange(tx);
                        }
                    }
                    else
                    {
                        valid = false;
                        Console.WriteLine("failed on transaction verification: missing message hash");
                    }

                    // fail if deposit hash not present in payout transaction
                    if ((t.transaction.otherTrans == null ? t.transaction.message?.payload : t.transaction.otherTrans.message?.payload) != null)
                    {
                        // find deposit transaction based on hash in message
                        var tx = txs.Single(x => x.meta.hash.data == Encoding.UTF8.GetString(CryptoBytes.FromHexString((t.transaction.type == 257 ? t.transaction.message.payload : t.transaction.otherTrans.message.payload))));

                        // initiate mosaic client
                        var mosaicClient = new NamespaceMosaicClient(Con);

                        var mosaicDivisibility = 0;

                        var mosaics = ConfigurationManager.GetSection("MosaicConfigElement") as MyMosaicConfigSection;

                        foreach (MosaicConfigElement m in mosaics.Mosaics)
                        {
                            // retrieve mosaic definition for rate calculation
                            mosaicClient.BeginGetMosaicsByNameSpace(ar3 =>
                            {
                                foreach (var m2 in t.transaction.otherTrans.mosaics)
                                {
                                    if (!(m2.mosaicId.namespaceId == m.MosaicNameSpace && m2.mosaicId.name == m.MosaicID))
                                    {
                                        continue;
                                    }

                                    if (ar3.Ex != null)
                                    {
                                        Console.WriteLine(ar3.Ex);
                                    } // if no error, set mosaic divisibility
                                    else
                                    {
                                        mosaicDivisibility = int.Parse(ar3.Content.Data[0].Mosaic.Properties[0].Value);
                                    }

                                    var depositedAmount = Calculations.GetDepositedAmount(tx);

                                    // calculate based on pre-set currency denomination
                                    if (m.CostDenomination == "USD")
                                    {
                                        // fail if no mosaics present in ico payout transaction
                                        if (t.transaction.otherTrans.mosaics != null)
                                        {
                                            // check if the mosaic quantity paid out is correct for the deposit
                                            var amountValid = Calculations.RateCalculation(depositedAmount, mosaicDivisibility, m) == m2.quantity;

                                            // check the recipient of the payout is the signer of the deposit, fail if not.
                                            if (amountValid && t.transaction.otherTrans.recipient == AddressEncoding.ToEncoded(Con.GetNetworkVersion(), new CSharp2nem.Model.AccountSetup.PublicKey(tx.transaction.otherTrans?.signer == null ? tx.transaction.signer : tx.transaction.otherTrans.signer)))
                                            {
                                                continue;
                                            }
                                            else
                                            {
                                                Console.WriteLine("failed on transaction verification: amount or recipient is invalid");
                                                valid = false;
                                            }
                                        }
                                        else
                                        {
                                            Console.WriteLine("failed on transaction verification: invalid or missing mosaic");
                                        }
                                    }
                                    else if (m.CostDenomination == "XEM")
                                    {
                                        // set mosaic amount paid out.
                                        var q = m2.quantity;

                                        // get amount that should be paid out for the deposit
                                        var a = Calculations.BonusCalculation(m, Math.Ceiling((depositedAmount / decimal.Parse(m.MosaicCost)) / (decimal)Math.Pow(10, 6 - mosaicDivisibility)));

                                        // if incorrect, fail
                                        valid = a == q ? true : false;

                                        if (!valid)
                                        {
                                            Console.WriteLine("failed on transaction verification: amounts do not match");
                                        }
                                    }
                                    else
                                    {
                                        Console.WriteLine("failed on transaction verification: incorrect currency");
                                    }
                                }
                            }, m.MosaicNameSpace, m.MosaicID).AsyncWaitHandle.WaitOne();
                        }
                    }
                    else
                    {
                        Console.WriteLine("failed on transaction verification: missing hash");
                    }
                }
            }, t.transaction.otherTrans.signer).AsyncWaitHandle.WaitOne();

            return(valid);
        }