Beispiel #1
0
    def transfer_from_multisig_wallet(self, ticker, quantity, destination,
                                      multisig):
        contract = accounting.get_contract(self.session, ticker)
        if destination == "onlinecash":
            address = yield self.get_current_address("multisigcash", ticker)
        elif destination == "offlinecash":
            address = contract.cold_wallet_address
        else:
            raise NotImplementedError

        result = yield self.send_to_address(ticker,
                                            address,
                                            quantity,
                                            multisig=multisig)
        txid = result['txid']
        fee = result['fee']

        # Record fees
        fee_uid = util.get_uid()
        note = "%s: %s" % (address, txid)

        # CREDIT the from account
        fee_d1 = self.accountant.transfer_position('multisigcash', ticker,
                                                   'credit', fee, note,
                                                   fee_uid)

        # DEBIT the customer account
        fee_d2 = self.accountant.transfer_position('customer', ticker, 'debit',
                                                   fee, note, fee_uid)
        yield defer.gatherResults([fee_d1, fee_d2], consumeErrors=True)

        if destination == "offlinecash":
            # Record the transfer
            uid = util.get_uid()
            # CREDIT the from account
            d1 = self.accountant.transfer_position('multisigcash', ticker,
                                                   'credit', quantity, note,
                                                   uid)
            # DEBIT the to account
            d2 = self.accountant.transfer_position('offlinecash', ticker,
                                                   'debit', quantity, note,
                                                   uid)
            yield defer.gatherResults([d1, d2])
        else:
            # If going to online cash the transfer will get recorded when the btc arrives
            pass

        returnValue(txid)
Beispiel #2
0
    def transfer_from_multisig_wallet(self, ticker, quantity, destination, multisig):
        contract = accounting.get_contract(self.session, ticker)
        if destination == "onlinecash":
            address = yield self.get_current_address("multisigcash", ticker)
        elif destination == "offlinecash":
            address = contract.cold_wallet_address
        else:
            raise NotImplementedError

        result = yield self.send_to_address(ticker, address, quantity, multisig=multisig)
        txid = result['txid']
        fee = result['fee']

        # Record fees
        fee_uid = util.get_uid()
        note = "%s: %s" % (address, txid)

        # CREDIT the from account
        fee_d1 = self.accountant.transfer_position('multisigcash', ticker, 'credit', fee, note, fee_uid)

        # DEBIT the customer account
        fee_d2 = self.accountant.transfer_position('customer', ticker, 'debit', fee, note, fee_uid)
        yield defer.gatherResults([fee_d1, fee_d2], consumeErrors=True)

        if destination == "offlinecash":
            # Record the transfer
            uid = util.get_uid()
            # CREDIT the from account
            d1=self.accountant.transfer_position('multisigcash', ticker, 'credit', quantity,
                                              note, uid)
            # DEBIT the to account
            d2=self.accountant.transfer_position('offlinecash', ticker, 'debit', quantity, note, uid)
            yield defer.gatherResults([d1, d2])
        else:
            # If going to online cash the transfer will get recorded when the btc arrives
            pass

        returnValue(txid)
Beispiel #3
0
    def send_to_address(self, ticker, address, amount, multisig={}):
        if self.testnet:
            network = "XTN"
        else:
            network = "BTC"

        if is_address_valid(address) != network:
            raise INVALID_ADDRESS

        contract = accounting.get_contract(self.session, ticker)
        if not multisig:
            withdrawal_amount = float(conversions.quantity_from_wire(contract, amount))
            try:
                result = yield self.bitcoinrpc[ticker].getbalance()
            except Exception as e:
                log.err("Unable to get wallet balance: %s" % str(e))
                raise e

            balance = result['result']
            if balance >= withdrawal_amount:
                try:
                    result = yield self.bitcoinrpc[ticker].sendtoaddress(address, withdrawal_amount)
                    txid = result['result']
                    tx = yield self.bitcoinrpc[ticker].gettransaction(txid)
                    # The fee shows up from gettransaction as a negative number,
                    # but we want a positive number
                    fee = abs(long(round(tx['result']['fee'] * contract.denominator)))

                except Exception as e:
                    log.err("Unable to send to address: %s" % str(e))
                    raise e
            else:
                raise INSUFFICIENT_FUNDS
        else:
            self.bitgo.token = multisig['token'].encode('utf-8')
            try:
                yield self.bitgo.unlock(multisig['otp'])
            except Exception as e:
                log.err("Unable to unlock multisig")
                raise OTP_INVALID

            wallet_id = contract.multisig_wallet_address
            try:
                wallet = yield self.bitgo.wallets.get(wallet_id)
            except Exception as e:
                log.err("Unable to get wallet details")
                log.err(e)
                raise e

            balance = wallet.balance
            if balance < amount:
                raise INSUFFICIENT_FUNDS

            if not os.path.exists(self.bitgo_private_key_file):
                raise NO_KEY_FILE
            else:
                with open(self.bitgo_private_key_file, "rb") as f:
                    key_data = json.load(f)
                    passphrase = key_data['passphrase']

            try:
                result = yield wallet.sendCoins(address=address, amount=amount,
                        passphrase=passphrase)
                txid = result['tx']
                fee = result['fee']
            except Exception as e:
                log.err("Unable to sendCoins")
                log.err(e)
                raise e

        returnValue({'txid': txid,
                     'fee': fee})
Beispiel #4
0
    def send_to_address(self, ticker, address, amount, multisig={}):
        if self.testnet:
            network = "XTN"
        else:
            network = "BTC"

        if is_address_valid(address) != network:
            raise INVALID_ADDRESS

        contract = accounting.get_contract(self.session, ticker)
        if not multisig:
            withdrawal_amount = float(
                conversions.quantity_from_wire(contract, amount))
            try:
                result = yield self.bitcoinrpc[ticker].getbalance()
            except Exception as e:
                log.err("Unable to get wallet balance: %s" % str(e))
                raise e

            balance = result['result']
            if balance >= withdrawal_amount:
                try:
                    result = yield self.bitcoinrpc[ticker].sendtoaddress(
                        address, withdrawal_amount)
                    txid = result['result']
                    tx = yield self.bitcoinrpc[ticker].gettransaction(txid)
                    # The fee shows up from gettransaction as a negative number,
                    # but we want a positive number
                    fee = abs(
                        long(round(tx['result']['fee'] *
                                   contract.denominator)))

                except Exception as e:
                    log.err("Unable to send to address: %s" % str(e))
                    raise e
            else:
                raise INSUFFICIENT_FUNDS
        else:
            self.bitgo.token = multisig['token'].encode('utf-8')
            try:
                yield self.bitgo.unlock(multisig['otp'])
            except Exception as e:
                log.err("Unable to unlock multisig")
                raise OTP_INVALID

            wallet_id = contract.multisig_wallet_address
            try:
                wallet = yield self.bitgo.wallets.get(wallet_id)
            except Exception as e:
                log.err("Unable to get wallet details")
                log.err(e)
                raise e

            balance = wallet.balance
            if balance < amount:
                raise INSUFFICIENT_FUNDS

            if not os.path.exists(self.bitgo_private_key_file):
                raise NO_KEY_FILE
            else:
                with open(self.bitgo_private_key_file, "rb") as f:
                    key_data = json.load(f)
                    passphrase = key_data['passphrase']

            try:
                result = yield wallet.sendCoins(address=address,
                                                amount=amount,
                                                passphrase=passphrase)
                txid = result['tx']
                fee = result['fee']
            except Exception as e:
                log.err("Unable to sendCoins")
                log.err(e)
                raise e

        returnValue({'txid': txid, 'fee': fee})