Ejemplo n.º 1
0
        /// <summary>	Refund bitshares deposit. </summary>
        ///
        /// <remarks>	Paul, 15/01/2015. </remarks>
        ///
        /// <param name="fromAccount">	from account. </param>
        /// <param name="deposit">	    The deposit. </param>
        /// <param name="depositId">    Identifier for the deposit. </param>
        /// <param name="memo">		    The memo. </param>
        protected virtual void RefundBitsharesDeposit(string fromAccount, ulong larimers, string depositId, string memo)
        {
            // make sure failures after this point don't result in multiple refunds
            MarkTransactionAsRefundedStart(depositId);

            BitsharesTransactionResponse response;
            decimal amount = m_asset.GetAmountFromLarimers(larimers);

            try
            {
                BitsharesAccount account = GetAccountFromLedger(fromAccount);
                response = m_bitshares.WalletTransfer(amount, m_asset.symbol, m_bitsharesAccount, fromAccount, memo);
            }
            catch (BitsharesRpcException)
            {
                BitsharesTransaction t = m_bitshares.BlockchainGetTransaction(depositId);

                // get the sender's address from the balance id
                BitsharesOperation op = t.trx.operations.First(o => o.type == BitsharesTransactionOp.withdraw_op_type);

                BitsharesBalanceRecord balance = m_bitshares.GetBalance(op.data.balance_id);
                string senderAddress           = balance.condition.data.owner;


                response = m_bitshares.WalletTransferToAddress(amount, m_asset.symbol, m_bitsharesAccount, senderAddress, memo);
            }

            MarkTransactionAsRefundedEnd(depositId, response.record_id, amount, DaemonTransactionType.bitsharesRefund, memo);
        }
Ejemplo n.º 2
0
        /// <summary>	Bitshares account to bitcoin address. </summary>
        ///
        /// <remarks>	Paul, 15/01/2015. </remarks>
        ///
        /// <param name="account">	The account. </param>
        ///
        /// <returns>	A string. </returns>
        protected string BitsharesAccountToBitcoinAddress(BitsharesAccount account)
        {
            // turn that into a BTC address
            BitsharesPubKey pubKey = new BitsharesPubKey(account.active_key_history.Last().Values.Last());

            return(pubKey.ToBitcoinAddress(true, m_addressByteType));
        }
Ejemplo n.º 3
0
        /// <summary>	Sends the bitcoins to depositor. </summary>
        ///
        /// <remarks>	Paul, 05/02/2015. </remarks>
        ///
        /// <exception cref="RefundBitsharesException">	Thrown when a Refund Bitshares error condition
        ///                                             occurs. </exception>
        ///
        /// <param name="btcAddress">	The btc address. </param>
        /// <param name="trxId">	    Identifier for the trx. </param>
        /// <param name="amount">	    The amount. </param>
        /// <param name="asset">	    The asset. </param>
        ///
        /// <returns>	A string. </returns>
        protected virtual string SendBitcoinsToDepositor(string btcAddress, string trxId, ulong amount, BitsharesAsset asset,
                                                         string depositAddress, MetaOrderType orderType, bool burnUia)
        {
            // make sure failures after this point dont result in multiple credits
            m_daemon.MarkDespositAsCreditedStart(trxId, depositAddress, m_market.symbol_pair, orderType);

            decimal bitAssetAmount = asset.GetAmountFromLarimers(amount);

            if (bitAssetAmount > m_market.bid_max)
            {
                throw new RefundBitsharesException("Over " + Numeric.SerialisedDecimal(m_market.bid_max) + " " + asset.symbol + "!");
            }

            // get the BTC amount we need to transfer
            decimal btcNoFee;

            if (m_flipped)
            {
                // they're sending us bitAssets, not BTC because the market is flipped, this is
                // equivelent to the opposite order type, so we have to use ask here
                btcNoFee = bitAssetAmount / m_market.ask;
            }
            else
            {
                btcNoFee = bitAssetAmount * m_market.bid;
            }

            // when selling, the fee is charged in BTC,
            // the amount recorded in the transaction is the amount of bitAssets sans fee, obv

            decimal fee      = (m_market.bid_fee_percent / 100) * btcNoFee;
            decimal btcTotal = Numeric.TruncateDecimal(btcNoFee - fee, 8);

            // do the transfer
            string txid = m_bitcoin.SendToAddress(btcAddress, btcTotal, "mX: " + orderType + " " + asset.symbol);

            // mark this in our records
            m_daemon.MarkDespositAsCreditedEnd(trxId, txid, MetaOrderStatus.completed, bitAssetAmount, m_market.bid, fee);

            if (burnUia)
            {
                // make sure we were the issuer for this asset before we start burning it!
                BitsharesAccount account = m_bitshares.WalletGetAccount(m_bitsharesAccount);
                if (asset.issuer_id == account.id)
                {
                    m_bitshares.WalletBurn(bitAssetAmount, asset.symbol, m_bitsharesAccount, BurnForOrAgainst.@for, m_bitsharesAccount);
                }
            }

            return(txid);
        }
Ejemplo n.º 4
0
        /// <summary>	Sends bitAssets, either issue or transfer them </summary>
        ///
        /// <remarks>	Paul, 18/03/2015. </remarks>
        ///
        /// <param name="amount">       The amount. </param>
        /// <param name="asset">		The asset. </param>
        /// <param name="sendTo">	to account. </param>
        ///
        /// <returns>	A BitsharesTransactionResponse. </returns>
        protected BitsharesTransactionResponse SendBitAssets(decimal amount, BitsharesAsset asset, string sendTo, string memo = "", bool allowIssue = true)
        {
            BitsharesAccount account = m_bitshares.WalletGetAccount(m_bitsharesAccount);

            if (asset.issuer_id == account.id && allowIssue)
            {
                // issue it
                return(m_bitshares.WalletUiaIssue(amount, asset.symbol, sendTo, memo));
            }
            else
            {
                // transfer it
                return(m_bitshares.WalletTransfer(amount, asset.symbol, m_bitsharesAccount, sendTo, memo));
            }
        }
Ejemplo n.º 5
0
        /// <summary>	This is virtual because implementors might like a different way  </summary>
        ///
        /// <remarks>	Paul, 16/12/2014. </remarks>
        ///
        /// <param name="account">	The account. </param>
        ///
        /// <returns>	A string. </returns>

        /*protected virtual string BitsharesTransactionToBitcoinAddress(BitsharesLedgerEntry l)
         * {
         *      // THIS CANNOT WORK DUE TO MEMO SIZE = 19 bytes!!!!!!!
         *
         *
         *      // expect the BTC address to be inside the memo somewhere
         *      string[] memo = l.memo.Split(' ');
         *      AddressBase address = null;
         *      foreach (string s in memo)
         *      {
         *              try
         *              {
         *                      address = new AddressBase(s);
         *                      break;
         *              }
         *              catch (ArgumentException){}
         *      }
         *
         *      if (address == null)
         *      {
         *              throw new RefundBitsharesException("Unable to find desired bitcoin address in transction memo!");
         *      }
         *
         *      return address.AddressBase58;
         * }*/

        /// <summary>	Bitshares transaction to bitcoin address. </summary>
        ///
        /// <remarks>	Paul, 25/01/2015. </remarks>
        ///
        /// <exception cref="RefundBitsharesException">	Thrown when a Refund Bitshares error condition
        ///                                             occurs. </exception>
        ///
        /// <param name="l">	The BitsharesLedgerEntry to process. </param>
        /// <param name="t">	The TransactionSinceBlock to process. </param>
        ///
        /// <returns>	A string. </returns>
        protected virtual string BitsharesTransactionToBitcoinAddress(BitsharesLedgerEntry l, BitsharesTransaction t)
        {
            try
            {
                // get the public key of the sender
                BitsharesAccount account = GetAccountFromLedger(l.from_account);

                // turn into into a bitshares address
                return(BitsharesAccountToBitcoinAddress(account));
            }
            catch (BitsharesRpcException)
            {
                throw new RefundBitsharesException("Unregistered acct!");
            }
        }
Ejemplo n.º 6
0
 /// <summary>	Bitshares account to bitcoin address. </summary>
 ///
 /// <remarks>	Paul, 15/01/2015. </remarks>
 ///
 /// <param name="account">	The account. </param>
 ///
 /// <returns>	A string. </returns>
 protected string BitsharesAccountToBitcoinAddress(BitsharesAccount account)
 {
     // turn that into a BTC address
     BitsharesPubKey pubKey = new BitsharesPubKey(account.active_key_history.Last().Values.Last());
     return pubKey.ToBitcoinAddress(true, m_addressByteType);
 }
Ejemplo n.º 7
0
        /// <summary>	Executes the submit address action. </summary>
        ///
        /// <remarks>	Paul, 05/02/2015. </remarks>
        ///
        /// <exception cref="ApiExceptionMessage">	    Thrown when an API exception message error
        ///                                             condition occurs. </exception>
        /// <exception cref="UnexpectedCaseException">	Thrown when an Unexpected Case error condition
        ///                                             occurs. </exception>
        ///
        /// <param name="receivingAddress">	The receiving address. </param>
        /// <param name="orderType">	    Type of the order. </param>
        ///
        /// <returns>	A SubmitAddressResponse. </returns>
        public override SubmitAddressResponse OnSubmitAddress(string receivingAddress, MetaOrderType orderType, uint referralUser)
        {
            SubmitAddressResponse response;

            if (orderType == MetaOrderType.buy)
            {
                string accountName = receivingAddress;
                bool   isPublicKey = BitsharesPubKey.IsValidPublicKey(accountName);

                // check for theoretical validity

                if (!isPublicKey && !BitsharesWallet.IsValidAccountName(accountName))
                {
                    throw new ApiExceptionInvalidAccount(accountName);
                }

                // try and retrieve a previous entry
                SenderToDepositRow senderToDeposit = m_daemon.GetSenderDepositFromReceiver(accountName, m_market.symbol_pair, referralUser);
                if (senderToDeposit == null)
                {
                    // no dice, create a new entry

                    // check for actual validity
                    string rcA;

                    if (!isPublicKey)
                    {
                        BitsharesAccount account = m_bitshares.GetAccount(accountName);
                        if (account == null)
                        {
                            throw new ApiExceptionInvalidAccount(accountName);
                        }

                        rcA = account.name;
                    }
                    else
                    {
                        rcA = accountName;
                    }

                    // generate a new bitcoin address and tie it to this account
                    string depositAdress = m_bitcoin.GetNewAddress();
                    senderToDeposit = m_daemon.InsertSenderToDeposit(rcA, depositAdress, m_market.symbol_pair, referralUser);
                }

                response = new SubmitAddressResponse
                {
                    deposit_address   = senderToDeposit.deposit_address,
                    receiving_address = senderToDeposit.receiving_address
                };
            }
            else if (orderType == MetaOrderType.sell)
            {
                string bitcoinAddress = receivingAddress;

                // validate bitcoin address
                byte[] check = Util.Base58CheckToByteArray(bitcoinAddress);
                if (check == null)
                {
                    throw new ApiExceptionInvalidAddress(bitcoinAddress);
                }

                // try and retrieve a previous entry
                SenderToDepositRow senderToDeposit = m_daemon.GetSenderDepositFromReceiver(bitcoinAddress, m_market.symbol_pair, referralUser);
                if (senderToDeposit == null)
                {
                    // generate a memo field to use instead
                    senderToDeposit = m_daemon.InsertSenderToDeposit(bitcoinAddress, MarketBase.CreateMemo(bitcoinAddress, m_market.symbol_pair, referralUser), m_market.symbol_pair, referralUser);
                }

                response = new SubmitAddressResponse
                {
                    deposit_address   = m_bitsharesAccount,
                    receiving_address = senderToDeposit.receiving_address,
                    memo = senderToDeposit.deposit_address
                };
            }
            else
            {
                throw new UnexpectedCaseException();
            }

            return(response);
        }
Ejemplo n.º 8
0
        /// <summary>	Calculates the market prices and limits. </summary>
        ///
        /// <remarks>	Paul, 05/02/2015. </remarks>
        ///
        /// <param name="market">				[in,out] The market. </param>
        /// <param name="bitsharesBalances">	The bitshares balances. </param>
        /// <param name="bitcoinBalance">       The bitcoin balance. </param>
        public override void ComputeMarketPricesAndLimits(ref MarketRow market,
                                                          Dictionary <int, ulong> bitsharesBalances,
                                                          decimal bitcoinBalance)
        {
            base.ComputeMarketPricesAndLimits(ref market, bitsharesBalances, bitcoinBalance);

            decimal baseBalance  = 0;
            decimal quoteBalance = bitcoinBalance;

            if (bitsharesBalances.ContainsKey(m_asset.id))
            {
                // only non zero balances return data, so this guard is necessary
                baseBalance = m_asset.GetAmountFromLarimers(bitsharesBalances[m_asset.id]);
            }

            decimal maxTransactionFactor;

            if (m_currency.uia)
            {
                // with UIA we got to handle the maximum buy size differently
                BitsharesAccount account = m_bitshares.WalletGetAccount(m_bitsharesAccount);
                if (m_asset.issuer_id == account.id)
                {
                    // we are the issuer!

                    // refresh the asset
                    m_asset = m_bitshares.BlockchainGetAsset(m_asset.symbol);

                    // this is how much we can issue, so lets stick that in there
                    baseBalance = m_asset.GetAmountFromLarimers(m_asset.max_supply - m_asset.current_supply);
                }
                else
                {
                    throw new UnexpectedCaseException();
                }

                maxTransactionFactor = 1;
                //maxTransactionFactor = kMaxTransactionFactor;
            }
            else
            {
                maxTransactionFactor = kMaxTransactionFactor;
            }

            decimal newAskMax, newBidMax;

            // askMax is in BITCOINS
            // bidMax is in BITASSETS

            if (m_flipped)
            {
                // BTC_bitUSD

                // baseBalance = 10 bitUSD
                // ask = 240
                // askMax = 10 / 240 = 0.04 BTC

                newAskMax = Numeric.TruncateDecimal((baseBalance / m_market.ask) * maxTransactionFactor, 8);
                newBidMax = Numeric.TruncateDecimal((quoteBalance * m_market.bid) * maxTransactionFactor, 8);
            }
            else
            {
                // BTS_BTC
                //
                // baseBalance = 1 BTS
                // ask = 0.00004
                // askMax = 1 * 0.0004 = 0.0004 BTC

                newAskMax = Numeric.TruncateDecimal((baseBalance * m_market.ask) * maxTransactionFactor, 8);
                newBidMax = Numeric.TruncateDecimal((quoteBalance / m_market.bid) * maxTransactionFactor, 8);
            }

            m_isDirty |= newAskMax != m_market.ask_max || newBidMax != m_market.bid_max;

            market.ask_max = newAskMax;
            market.bid_max = newBidMax;

            if (m_market.price_discovery)
            {
                //
                // update price discovery engine
                //

                decimal bitsharesBalance = m_asset.GetAmountFromLarimers(bitsharesBalances[m_asset.id]);

                if (m_asset.symbol == CurrencyHelpers.kBtcSymbol)
                {
                    m_lastFeedPrice = 1;
                }
                else
                {
                    m_lastFeedPrice = RecomputeFeedPriceInBtc();
                }

                decimal inventoryRatio = ComputeInventoryRatio(bitsharesBalances, bitcoinBalance);

                if (m_prices == null)
                {
                    //
                    // initialise the price discovery engine
                    //

                    m_prices = new PriceDiscovery(market.spread_percent, market.window_percent, m_lastFeedPrice, inventoryRatio);
                }

                decimal oldBid = m_market.bid;
                decimal oldAsk = m_market.ask;
                m_prices.UpdateParameters(m_lastFeedPrice, inventoryRatio, m_market.spread_percent, m_market.window_percent, out m_market.bid, out m_market.ask);

                m_isDirty |= oldBid != m_market.bid || oldAsk != m_market.ask;
            }
        }
Ejemplo n.º 9
0
        /// <summary>	Executes the submit address action. </summary>
        ///
        /// <remarks>	Paul, 25/01/2015. </remarks>
        ///
        /// <exception cref="ApiExceptionMessage">		    Thrown when an API exception message error
        ///                                                 condition occurs. </exception>
        /// <exception cref="ApiExceptionMissingParameter">	Thrown when an API exception missing
        ///                                                 parameter error condition occurs. </exception>
        ///
        /// <param name="ctx">      The context. </param>
        /// <param name="dummy">	The dummy. </param>
        ///
        /// <returns>	A Task. </returns>
        Task OnSubmitAddress(RequestContext ctx, IDummy dummy)
        {
            CurrencyTypes fromCurrency     = RestHelpers.GetPostArg <CurrencyTypes, ApiExceptionMissingParameter>(ctx, WebForms.kFromCurrency);
            CurrencyTypes toCurrency       = RestHelpers.GetPostArg <CurrencyTypes, ApiExceptionMissingParameter>(ctx, WebForms.kToCurrency);
            string        receivingAddress = RestHelpers.GetPostArg <string, ApiExceptionMissingParameter>(ctx, WebForms.kReceivingAddress);

            SubmitAddressResponse response;

            if (fromCurrency == CurrencyTypes.BTC && toCurrency == CurrencyTypes.bitBTC)
            {
                string accountName = receivingAddress;

                // try and retrieve a previous entry
                SenderToDepositRow senderToDeposit = m_database.Query <SenderToDepositRow>("SELECT * FROM sender_to_deposit WHERE receiving_address=@s;", accountName).FirstOrDefault();
                if (senderToDeposit == null || !BitsharesWallet.IsValidAccountName(accountName))
                {
                    // no dice, create a new entry

                    // validate bitshares account name
                    try
                    {
                        BitsharesAccount account = m_bitshares.WalletGetAccount(accountName);

                        // generate a new bitcoin address and tie it to this account
                        string depositAdress = m_bitcoin.GetNewAddress();
                        senderToDeposit = InsertSenderToDeposit(account.name, depositAdress);
                    }
                    catch (BitsharesRpcException)
                    {
                        throw new ApiExceptionMessage(accountName + " is not an existing account! Are you sure it is registered?");
                    }
                }

                response = new SubmitAddressResponse {
                    deposit_address = senderToDeposit.deposit_address
                };
            }
            else if (fromCurrency == CurrencyTypes.bitBTC && toCurrency == CurrencyTypes.BTC)
            {
                string bitcoinAddress = receivingAddress;

                // try and retrieve a previous entry
                SenderToDepositRow senderToDeposit = m_database.Query <SenderToDepositRow>("SELECT * FROM sender_to_deposit WHERE receiving_address=@s;", bitcoinAddress).FirstOrDefault();
                if (senderToDeposit == null)
                {
                    // validate bitcoin address
                    byte[] check = Util.Base58CheckToByteArray(bitcoinAddress);
                    if (check == null)
                    {
                        throw new ApiExceptionMessage(bitcoinAddress + " is not a valid bitcoin address!");
                    }

                    // generate a memo field to use instead
                    string start = "meta-";
                    string memo  = start + bitcoinAddress.Substring(0, BitsharesWallet.kBitsharesMaxMemoLength - start.Length);
                    senderToDeposit = InsertSenderToDeposit(bitcoinAddress, memo);
                }

                response = new SubmitAddressResponse {
                    deposit_address = m_bitsharesAccount, memo = senderToDeposit.deposit_address
                };
            }
            else
            {
                throw new ApiExceptionUnsupportedTrade(fromCurrency, toCurrency);
            }

            ctx.Respond <SubmitAddressResponse>(response);

            return(null);
        }