diff --git a/lbrynet/daemon/Daemon.py b/lbrynet/daemon/Daemon.py
index 10b47d43e..d0985f42c 100644
--- a/lbrynet/daemon/Daemon.py
+++ b/lbrynet/daemon/Daemon.py
@@ -1,5 +1,3 @@
-# coding=utf-8
-import binascii
 import logging.handlers
 import mimetypes
 import os
@@ -7,6 +5,9 @@ import requests
 import urllib
 import json
 import textwrap
+import signal
+import six
+from binascii import hexlify, unhexlify, b2a_hex
 from copy import deepcopy
 from decimal import Decimal, InvalidOperation
 from twisted.web import server
@@ -14,6 +15,8 @@ from twisted.internet import defer, reactor
 from twisted.internet.task import LoopingCall
 from twisted.python.failure import Failure
 
+from torba.constants import COIN
+
 import lbryschema
 from lbryschema.claim import ClaimDict
 from lbryschema.uri import parse_lbry_uri
@@ -231,6 +234,10 @@ class Daemon(AuthJSONRPCServer):
         # TODO: delete this
         self.streams = {}
 
+    @property
+    def ledger(self):
+        return self.session.wallet.default_account.ledger
+
     @defer.inlineCallbacks
     def setup(self):
         log.info("Starting lbrynet-daemon")
@@ -511,7 +518,7 @@ class Daemon(AuthJSONRPCServer):
 
     @defer.inlineCallbacks
     def _get_lbry_file_dict(self, lbry_file, full_status=False):
-        key = binascii.b2a_hex(lbry_file.key) if lbry_file.key else None
+        key = b2a_hex(lbry_file.key) if lbry_file.key else None
         full_path = os.path.join(lbry_file.download_directory, lbry_file.file_name)
         mime_type = mimetypes.guess_type(full_path)[0]
         if os.path.isfile(full_path):
@@ -1532,38 +1539,21 @@ class Daemon(AuthJSONRPCServer):
                 'claim_id' : (str) claim ID of the resulting claim
             }
         """
-
-        try:
-            parsed = parse_lbry_uri(channel_name)
-            if not parsed.is_channel:
-                raise Exception("Cannot make a new channel for a non channel name")
-            if parsed.path:
-                raise Exception("Invalid channel uri")
-        except (TypeError, URIParseError):
-            raise Exception("Invalid channel name")
-        if amount <= 0:
-            raise Exception("Invalid amount")
-
-        yield self.wallet.update_balance()
-        if amount >= self.wallet.get_balance():
-            balance = yield self.wallet.get_max_usable_balance_for_claim(channel_name)
-            max_bid_amount = balance - MAX_UPDATE_FEE_ESTIMATE
-            if balance <= MAX_UPDATE_FEE_ESTIMATE:
-                raise InsufficientFundsError(
-                    "Insufficient funds, please deposit additional LBC. Minimum additional LBC needed {}"
-                        .format(MAX_UPDATE_FEE_ESTIMATE - balance))
-            elif amount > max_bid_amount:
-                raise InsufficientFundsError(
-                    "Please wait for any pending bids to resolve or lower the bid value. "
-                    "Currently the maximum amount you can specify for this channel is {}"
-                    .format(max_bid_amount)
-                )
-
-        result = yield self.wallet.claim_new_channel(channel_name, amount)
+        tx = yield self.wallet.claim_new_channel(channel_name, amount)
+        script = tx.outputs[0].script
+        result = {
+            "success": True,
+            "txid": tx.hex_id.decode(),
+            "nout": 0,
+            "tx": hexlify(tx.raw),
+            "fee": str(Decimal(tx.fee) / COIN),
+            "claim_id": tx.get_claim_id(0),
+            "value": hexlify(script.values['claim']),
+            "claim_address": self.ledger.hash160_to_address(script.values['pubkey_hash'])
+        }
         self.analytics_manager.send_new_channel()
         log.info("Claimed a new channel! Result: %s", result)
-        response = yield self._render_response(result)
-        defer.returnValue(response)
+        defer.returnValue(result)
 
     @requires(WALLET_COMPONENT)
     @defer.inlineCallbacks
@@ -2628,7 +2618,7 @@ class Daemon(AuthJSONRPCServer):
         if not utils.is_valid_blobhash(blob_hash):
             raise Exception("invalid blob hash")
 
-        finished_deferred = self.dht_node.iterativeFindValue(binascii.unhexlify(blob_hash))
+        finished_deferred = self.dht_node.iterativeFindValue(unhexlify(blob_hash))
 
         def trap_timeout(err):
             err.trap(defer.TimeoutError)
diff --git a/lbrynet/tests/integration/wallet/test_commands.py b/lbrynet/tests/integration/wallet/test_commands.py
new file mode 100644
index 000000000..46a48050f
--- /dev/null
+++ b/lbrynet/tests/integration/wallet/test_commands.py
@@ -0,0 +1,56 @@
+import types
+
+from orchstr8.testcase import IntegrationTestCase, d2f
+from torba.constants import COIN
+
+import lbryschema
+lbryschema.BLOCKCHAIN_NAME = 'lbrycrd_regtest'
+
+from lbrynet import conf as lbry_conf
+from lbrynet.daemon.Daemon import Daemon
+from lbrynet.wallet.manager import LbryWalletManager
+
+
+class FakeAnalytics:
+    def send_new_channel(self):
+        pass
+
+
+class CommandTestCase(IntegrationTestCase):
+
+    WALLET_MANAGER = LbryWalletManager
+
+    async def setUp(self):
+        await super().setUp()
+
+        lbry_conf.settings = None
+        lbry_conf.initialize_settings(load_conf_file=False)
+        lbry_conf.settings['data_dir'] = self.stack.wallet.data_path
+        lbry_conf.settings['lbryum_wallet_dir'] = self.stack.wallet.data_path
+        lbry_conf.settings['download_directory'] = self.stack.wallet.data_path
+        lbry_conf.settings['use_upnp'] = False
+        lbry_conf.settings['blockchain_name'] = 'lbrycrd_regtest'
+        lbry_conf.settings['lbryum_servers'] = [('localhost', 50001)]
+        lbry_conf.settings['known_dht_nodes'] = []
+        lbry_conf.settings.node_id = None
+
+        await d2f(self.account.ensure_address_gap())
+        address = (await d2f(self.account.receiving.get_usable_addresses(1)))[0]
+        sendtxid = await self.blockchain.send_to_address(address.decode(), 10)
+        await self.on_transaction_id(sendtxid)
+        await self.blockchain.generate(1)
+        await self.on_transaction_id(sendtxid)
+        self.daemon = Daemon(FakeAnalytics())
+        self.daemon.session = types.SimpleNamespace()
+        self.daemon.session.wallet = self.manager
+
+
+class DaemonCommandsTests(CommandTestCase):
+
+    VERBOSE = True
+
+    async def test_new_channel(self):
+        result = await d2f(self.daemon.jsonrpc_channel_new('@bar', 1*COIN))
+        self.assertIn('txid', result)
+        await self.on_transaction_id(result['txid'])
+
diff --git a/lbrynet/wallet/account.py b/lbrynet/wallet/account.py
index 5d44a094d..0db56699c 100644
--- a/lbrynet/wallet/account.py
+++ b/lbrynet/wallet/account.py
@@ -13,5 +13,12 @@ def generate_certificate():
 class Account(BaseAccount):
 
     def __init__(self, *args, **kwargs):
-        super(BaseAccount, self).__init__(*args, **kwargs)
+        super(Account, self).__init__(*args, **kwargs)
         self.certificates = {}
+
+    def add_certificate(self, claim_id, key):
+        assert claim_id not in self.certificates, 'Trying to add a duplicate certificate.'
+        self.certificates[claim_id] = key
+
+    def get_certificate(self, claim_id):
+        return self.certificates[claim_id]
diff --git a/lbrynet/wallet/ledger.py b/lbrynet/wallet/ledger.py
index 66a2eb5e9..e45e87ce5 100644
--- a/lbrynet/wallet/ledger.py
+++ b/lbrynet/wallet/ledger.py
@@ -6,6 +6,7 @@ from torba.baseledger import BaseLedger
 from torba.baseheader import BaseHeaders, _ArithUint256
 from torba.util import int_to_hex, rev_hex, hash_encode
 
+from .account import Account
 from .network import Network
 from .database import WalletDatabase
 from .transaction import Transaction
@@ -88,6 +89,7 @@ class MainNetLedger(BaseLedger):
     symbol = 'LBC'
     network_name = 'mainnet'
 
+    account_class = Account
     database_class = WalletDatabase
     headers_class = Headers
     network_class = Network
diff --git a/lbrynet/wallet/manager.py b/lbrynet/wallet/manager.py
index 10608f4f8..0bede8251 100644
--- a/lbrynet/wallet/manager.py
+++ b/lbrynet/wallet/manager.py
@@ -6,8 +6,12 @@ from torba.constants import COIN
 from torba.coinselection import CoinSelector
 from torba.manager import WalletManager as BaseWalletManager
 
+from lbryschema.uri import parse_lbry_uri
+from lbryschema.error import URIParseError
 
 from .ledger import MainNetLedger
+from .account import generate_certificate
+from .transaction import Transaction
 
 
 class BackwardsCompatibleNetwork:
@@ -101,44 +105,28 @@ class LbryWalletManager(BaseWalletManager):
         return defer.succeed([])
 
     def claim_name(self, name, amount, claim):
-        amount = int(amount * COIN)
+        pass
 
+    @defer.inlineCallbacks
+    def claim_new_channel(self, channel_name, amount):
+        try:
+            parsed = parse_lbry_uri(channel_name)
+            if not parsed.is_channel:
+                raise Exception("Cannot make a new channel for a non channel name")
+            if parsed.path:
+                raise Exception("Invalid channel uri")
+        except (TypeError, URIParseError):
+            raise Exception("Invalid channel name")
+        if amount <= 0:
+            raise Exception("Invalid amount")
         account = self.default_account
-        coin = account.coin
-        ledger = coin.ledger
-
-        estimators = [
-            txo.get_estimator(coin) for txo in ledger.get_unspent_outputs()
-        ]
-
-        cost_of_output = coin.get_input_output_fee(
-            Output.pay_pubkey_hash(COIN, NULL_HASH)
-        )
-
-        selector = CoinSelector(estimators, amount, cost_of_output)
-        spendables = selector.select()
-        if not spendables:
-            raise ValueError('Not enough funds to cover this transaction.')
-
-        claim_address = account.get_least_used_receiving_address()
-        outputs = [
-            Output.pay_claim_name_pubkey_hash(
-                amount, name, claim, coin.address_to_hash160(claim_address)
-            )
-        ]
-
-        spent_sum = sum(s.effective_amount for s in spendables)
-        if spent_sum > amount:
-            change_address = account.get_least_used_change_address()
-            change_hash160 = coin.address_to_hash160(change_address)
-            outputs.append(Output.pay_pubkey_hash(spent_sum - amount, change_hash160))
-
-        tx = Transaction() \
-            .add_inputs([s.txi for s in spendables]) \
-            .add_outputs(outputs) \
-            .sign(account)
-
-        return tx
+        address = yield account.receiving.get_or_create_usable_address()
+        cert, key = generate_certificate()
+        tx = yield Transaction.claim(channel_name.encode(), cert, amount, address, [account], account)
+        yield account.ledger.broadcast(tx)
+        account.add_certificate(tx.get_claim_id(0), key)
+        # TODO: release reserved tx outputs in case anything fails by this point
+        defer.returnValue(tx)
 
 
 class ReservedPoints: