diff --git a/bfa_client/src/bfa/node.go b/bfa_client/src/bfa/node.go
index 063bd6902fffc05add92355fbcd221e5cb077dda..89c37d4765af9b084be8322a625001b24255d085 100644
--- a/bfa_client/src/bfa/node.go
+++ b/bfa_client/src/bfa/node.go
@@ -7,7 +7,9 @@ import (
 	"github.com/ethereum/go-ethereum/common"
 	"github.com/ethereum/go-ethereum/consensus/clique"
 	"github.com/ethereum/go-ethereum/core/types"
+	"github.com/ethereum/go-ethereum/p2p"
 	"github.com/ethereum/go-ethereum/rpc"
+	"math/big"
 	"sort"
 )
 
@@ -45,26 +47,61 @@ type SealerInfo struct {
 }
 
 type SealerStatus struct {
-	LastBlock  int64  `json:"lastBlockSigned"`
-	Time       uint64 `json:"timestamp"`
-	Difficulty uint64 `json:"difficulty"`
+	LastBlock  int64    `json:"lastBlockSigned"`
+	Time       uint64   `json:"timestamp"`
+	Difficulty uint64   `json:"difficulty"`
+	Balance    *big.Int `json:"balance"`
 }
 
 const (
-	Latest = "latest"
-	Self   = "self"
+	Latest  = "latest"
+	Self    = "self"
+	Network = 47525974938
+	Genesis = "0xe0e26f415af00fe32e1e8d94336355db43a78d9f59eb70910172b61fb670d99e"
 )
 
 func (node *Node) Call(result interface{}, method string, args ...interface{}) {
 	Check((*rpc.Client)(node).Call(result, method, args...))
 }
 
-func (node *Node) blockNumber() int64 {
+func (node *Node) BlockNumber() int64 {
 	var bn rpc.BlockNumber
 	node.Call(&bn, "eth_blockNumber")
 	return bn.Int64()
 }
 
+func (node *Node) Accounts() (accounts []string) {
+	node.Call(&accounts, "eth_accounts")
+	return
+}
+
+func (node *Node) IsMining() (mining bool) {
+	node.Call(&mining, "eth_mining")
+	return
+}
+
+func (node *Node) PeerCount() (peerCount int64) {
+	node.Call(&peerCount, "net_peerCount")
+	return
+}
+
+func (node *Node) BalanceAtBlock(account string, blockNumber int64) *big.Int {
+	var (
+		balance string
+		block   = Latest
+	)
+	if blockNumber >= 0 {
+		block = Int64ToHex(blockNumber)
+	}
+	node.Call(&balance, "eth_getBalance", account, block)
+	n, _ := new(big.Int).SetString(balance, 0)
+	return n
+}
+
+func (node *Node) Balance(account string) *big.Int {
+	return node.BalanceAtBlock(account, -1)
+}
+
 func (node *Node) Coinbase() (coinbase string, err error) {
 	defer func() {
 		if e := recover(); e != nil {
@@ -84,7 +121,7 @@ func (node *Node) Coinbase() (coinbase string, err error) {
 	return
 }
 
-func (node *Node) GetBlockByNumber(blockNumber int64) types.Header {
+func (node *Node) BlockByNumber(blockNumber int64) types.Header {
 	var (
 		number string
 		resp   types.Header
@@ -98,8 +135,8 @@ func (node *Node) GetBlockByNumber(blockNumber int64) types.Header {
 	return resp
 }
 
-func (node *Node) GetBlockSigner(blockNumber int64) (signer string) {
-	header := node.GetBlockByNumber(blockNumber)
+func (node *Node) BlockSigner(blockNumber int64) (signer string) {
+	header := node.BlockByNumber(blockNumber)
 	signer, err := GetSigner(&header)
 	Check(err)
 	return
@@ -110,12 +147,12 @@ func (node *Node) GetSnapshot() (snapshot Snapshot) {
 	return
 }
 
-func (node *Node) GetSnapshotAtHash(hash common.Hash) (snapshot Snapshot) {
+func (node *Node) SnapshotAtHash(hash common.Hash) (snapshot Snapshot) {
 	node.Call(&snapshot, "clique_getSnapshotAtHash", hash)
 	return
 }
 
-func (node *Node) GetSnapshotAtBlock(blockNumber int64) (snapshot Snapshot) {
+func (node *Node) SnapshotAtBlock(blockNumber int64) (snapshot Snapshot) {
 	if blockNumber < 0 {
 		return node.GetSnapshot()
 	}
@@ -123,7 +160,7 @@ func (node *Node) GetSnapshotAtBlock(blockNumber int64) (snapshot Snapshot) {
 	return
 }
 
-func (node *Node) GetSigners() (signers []string) {
+func (node *Node) Sealers() (signers []string) {
 	var s []common.Address
 	node.Call(&s, "clique_getSigners", nil)
 	for _, signer := range s {
@@ -132,7 +169,12 @@ func (node *Node) GetSigners() (signers []string) {
 	return
 }
 
-func (node *Node) GetSignersAtHash(hash common.Hash) (signers []string) {
+func (node *Node) NodeInfo() (nodeInfo p2p.NodeInfo) {
+	node.Call(&nodeInfo, "admin_nodeInfo", nil)
+	return
+}
+
+func (node *Node) SealersAtHash(hash common.Hash) (signers []string) {
 	var s []common.Address
 	node.Call(&signers, "clique_getSignersAtHash", hash)
 	for _, signer := range s {
@@ -141,10 +183,10 @@ func (node *Node) GetSignersAtHash(hash common.Hash) (signers []string) {
 	return
 }
 
-func (node *Node) GetSignersAtBlock(blockNumber int64) (signers []string) {
+func (node *Node) SealersAtBlock(blockNumber int64) (signers []string) {
 	var s []common.Address
 	if blockNumber < 0 {
-		return node.GetSigners()
+		return node.Sealers()
 	}
 	node.Call(&s, "clique_getSigners", Int64ToHex(blockNumber))
 	for _, signer := range s {
@@ -160,7 +202,7 @@ func (node *Node) IsSealer(address string) bool {
 			return false
 		}
 	}
-	return Contains(node.GetSigners(), address)
+	return Contains(node.Sealers(), address)
 }
 
 func (node *Node) Propose(address string, vote bool) {
@@ -168,14 +210,14 @@ func (node *Node) Propose(address string, vote bool) {
 	return
 }
 
-func (node *Node) GetVotes(blockNumber int64) (votes Proposals) {
+func (node *Node) Votes(blockNumber int64) (votes Proposals) {
 	var (
 		snapshot Snapshot
 	)
 	if blockNumber < 0 {
 		snapshot = node.GetSnapshot()
 	} else {
-		snapshot = node.GetSnapshotAtBlock(blockNumber)
+		snapshot = node.SnapshotAtBlock(blockNumber)
 	}
 	votes.BlockNumber = int64(snapshot.Number)
 	for signer := range snapshot.Signers {
@@ -213,11 +255,13 @@ func (node *Node) SealersStatus(blockNumber int64) (status map[string]*SealerSta
 		return
 	}
 	status = make(map[string]*SealerStatus)
-	for _, address := range node.GetSignersAtBlock(blockNumber) {
-		status[address] = &SealerStatus{}
+	for _, address := range node.SealersAtBlock(blockNumber) {
+		status[address] = &SealerStatus{
+			Balance: node.BalanceAtBlock(address, blockNumber),
+		}
 	}
 	notSeen := int64(len(status))
-	block := node.GetBlockByNumber(blockNumber)
+	block := node.BlockByNumber(blockNumber)
 	blockNumber = block.Number.Int64()
 	until := Max(1, blockNumber-5*notSeen)
 	for notSeen > 0 {
@@ -232,21 +276,21 @@ func (node *Node) SealersStatus(blockNumber int64) (status map[string]*SealerSta
 			break
 		}
 		blockNumber--
-		block = node.GetBlockByNumber(blockNumber)
+		block = node.BlockByNumber(blockNumber)
 	}
 	return status
 }
 
-func (node *Node) GetSealerInception(address string) (since int64) {
-	if signers := node.GetSigners(); !Contains(signers, address) {
+func (node *Node) SealerInception(address string) (since int64) {
+	if signers := node.Sealers(); !Contains(signers, address) {
 		return -1
 	}
 
 	lo := int64(0)
-	hi := node.blockNumber()
+	hi := node.BlockNumber()
 	for lo < hi {
 		mid := lo + (hi-lo)/2
-		signers := node.GetSignersAtBlock(mid)
+		signers := node.SealersAtBlock(mid)
 		if Contains(signers, address) {
 			hi = mid
 		} else {
@@ -256,11 +300,11 @@ func (node *Node) GetSealerInception(address string) (since int64) {
 	return hi
 }
 
-func (node *Node) getSignerFirstBlock(signer string, since int64, until int64) (blockNumber int64) {
+func (node *Node) signerFirstBlock(signer string, since int64, until int64) (blockNumber int64) {
 	if since < 0 {
 		return -1
 	}
-	//snapshot := node.GetSnapshotAtBlock(since)
+	//snapshot := node.SnapshotAtBlock(since)
 	var (
 		count int64 = 20
 		found int64 = -1
@@ -320,7 +364,7 @@ func (node *Node) getSignerFirstBlock(signer string, since int64, until int64) (
 	}
 }
 
-func (node *Node) getSignerLastBlock(signer string, since int64, until int64) (blockNumber int64) {
+func (node *Node) signerLastBlock(signer string, since int64, until int64) (blockNumber int64) {
 	if since < 0 {
 		return -1
 	}
@@ -390,7 +434,7 @@ func (node *Node) searchSnapshotForward(blockNumber int64, signer string, count
 		return
 	}
 	for count > 0 {
-		snapshot := node.GetSnapshotAtBlock(blockNumber + count - 1)
+		snapshot := node.SnapshotAtBlock(blockNumber + count - 1)
 		recents := int64(len(snapshot.Recents))
 		visited += recents
 		count -= recents
@@ -410,7 +454,7 @@ func (node *Node) searchSnapshotBackward(blockNumber int64, signer string, count
 	}
 	count = Min(count, blockNumber) // Never search below block 1
 	for {
-		snapshot := node.GetSnapshotAtBlock(blockNumber - visited)
+		snapshot := node.SnapshotAtBlock(blockNumber - visited)
 		visited += int64(len(snapshot.Recents))
 		if count == 0 {
 			count = Min(blockNumber, int64(2*len(snapshot.Signers)))
@@ -429,13 +473,13 @@ func (node *Node) searchSnapshotBackward(blockNumber int64, signer string, count
 
 func (node *Node) SealerInfo(sealer string) (info SealerInfo, err error) {
 	info.Address = sealer
-	info.CurrentBlock = node.blockNumber()
-	info.Since = node.GetSealerInception(sealer)
+	info.CurrentBlock = node.BlockNumber()
+	info.Since = node.SealerInception(sealer)
 	if info.Since == -1 {
 		return info, fmt.Errorf("%q is not a sealer", sealer)
 	}
-	info.FirstBlock = node.getSignerFirstBlock(sealer, info.Since+1, info.CurrentBlock)
-	info.LastBlock = node.getSignerLastBlock(sealer, info.FirstBlock, info.CurrentBlock)
+	info.FirstBlock = node.signerFirstBlock(sealer, info.Since+1, info.CurrentBlock)
+	info.LastBlock = node.signerLastBlock(sealer, info.FirstBlock, info.CurrentBlock)
 	return
 }
 
diff --git a/bfa_client/src/client/bfa_client.go b/bfa_client/src/client/bfa_client.go
index d2715c001e00c3f05b43f3067c06da2ade818d68..d29ed66817379756c4df2f761fc37259b11745bd 100644
--- a/bfa_client/src/client/bfa_client.go
+++ b/bfa_client/src/client/bfa_client.go
@@ -6,6 +6,7 @@ import (
 	"flag"
 	"fmt"
 	"log"
+	"math/big"
 	"os"
 	"path"
 	"sort"
@@ -26,7 +27,7 @@ var (
 	url         string
 	json        bool
 	help        bool
-	flags       flag.FlagSet
+	flags       = flag.NewFlagSet("", flag.ExitOnError)
 	command     string
 	description string
 	otherArgs   string
@@ -83,7 +84,7 @@ func proposals() {
 	node, err := bfa.Dial(url)
 	util.Check(err)
 	defer node.Close()
-	votes := node.GetVotes(blockNumber)
+	votes := node.Votes(blockNumber)
 	if json {
 		util.PrintJson(votes)
 		return
@@ -140,16 +141,21 @@ func parseFormatString(s string) (format string) {
 func sealers() {
 	var (
 		blockNumber int64
-		status      bool
+		lastBlock   bool
 		timestamp   bool
+		difficulty  bool
+		balance     bool
+		header      bool
 		format      string
-		length      int64 = 10 // timestamp length
 	)
 	description = "Presenta la lista de selladores. Opcionalmente indica el último bloque sellado por cada uno."
 	setFlags()
 	flags.Int64Var(&blockNumber, "block-number", latest, "Número del bloque en el cual se quiere conocer la lista de selladores (-1 para el último)")
-	flags.BoolVar(&status, "status", false, "Indica el último bloque sellado por cada sellador, o 0 si un nodo no ha sellado en las últimas 5 rondas.")
-	flags.BoolVar(&timestamp, "timestamp", false, "Muestra el timestamp del sellado en lugar del número de bloque.")
+	flags.BoolVar(&lastBlock, "last-block", false, "Muestra el último bloque sellado por cada sellador, o 0 si un nodo no ha sellado en las últimas 5 rondas.")
+	flags.BoolVar(&timestamp, "timestamp", false, "Muestra el timestamp del sellado.")
+	flags.BoolVar(&difficulty, "difficulty", false, "Muestra la dificultad del sellado (1: fuera de turno, 2: en turno).")
+	flags.BoolVar(&balance, "balance", false, "Muestra el saldo del sellador (en Wei).")
+	flags.BoolVar(&header, "header", true, "Muestra un encabezado en cada columna.")
 	flags.StringVar(&format, "format", "", "Formato del timestamp. Ignorado en formato json. Opciones: 'unix', 'rfc3339', 'long' ('YYYY-MM-DD hh:mm:ss'), 'short' ('hh:mm:ss') o un formato específico. Ejemplo 'DD/MM/YY hh.mm.ss'. También se admite el formato del paquete 'time' de go.")
 	parseFlags()
 	if blockNumber == 0 {
@@ -159,42 +165,80 @@ func sealers() {
 	node, err := bfa.Dial(url)
 	util.Check(err)
 	defer node.Close()
-	if status {
+	extended := lastBlock || timestamp || difficulty || balance
+	if extended {
 		sealers := node.SealersStatus(blockNumber)
 		if json {
 			util.PrintJson(sealers)
 			return
 		}
-		var list []string
+		var (
+			list         []string
+			lastBlockLen int64
+			timestampLen int64
+			balanceLen   int64
+		)
 		for sealer := range sealers {
 			list = append(list, sealer)
 		}
-		sort.Slice(list, func(i, j int) bool { return sealers[list[i]].LastBlock > sealers[list[j]].LastBlock })
-		if !timestamp {
-
-			length = util.Max(2, int64(len(strconv.FormatInt(sealers[list[0]].LastBlock, 10))))
-		} else {
+		switch {
+		case lastBlock:
+			sort.Slice(list, func(i, j int) bool { return sealers[list[i]].LastBlock > sealers[list[j]].LastBlock })
+		case timestamp:
+			sort.Slice(list, func(i, j int) bool { return sealers[list[i]].Time > sealers[list[j]].Time })
+		case difficulty:
+			sort.Slice(list, func(i, j int) bool { return sealers[list[i]].Difficulty > sealers[list[j]].Difficulty })
+		case balance:
+			sort.Slice(list, func(i, j int) bool { return sealers[list[i]].Balance.Cmp(sealers[list[j]].Balance) > 0 })
+		}
+		formatStr := "%42v"
+		if lastBlock {
+			formatStr += " %[2]*[3]v"
+			lastBlockLen = util.Max(2, int64(len(strconv.FormatInt(sealers[list[0]].LastBlock, 10))))
+		}
+		if timestamp {
+			formatStr += " %[4]*[5]v"
 			if len(format) > 0 {
 				format = parseFormatString(format)
-				length = int64(len(format))
+				timestampLen = int64(len(format))
+			} else {
+				timestampLen = 10
 			}
 		}
+		if difficulty {
+			formatStr += " %2[6]v"
+		}
+		if balance {
+			formatStr += " %[7]*[8]v"
+			balanceLen = 0
+			for _, s := range sealers {
+				balanceLen = util.Max(balanceLen, int64(len(s.Balance.String())))
+			}
+		}
+		formatStr += "\n"
+		if header {
+			fmt.Printf(formatStr,
+				fmt.Sprintf("%-24v", "Sealer"),
+				lastBlockLen, fmt.Sprintf("%*v", -lastBlockLen/2-2, "Last"),
+				timestampLen, fmt.Sprintf("%*v", -timestampLen/2-2, "Time"),
+				"Dif",
+				balanceLen, fmt.Sprintf("%*v", -balanceLen/2-4, "Balance"))
+		}
 		for _, sealer := range list {
-			var output interface{}
+			var formatedTimestamp interface{}
+			s := sealers[sealer]
 			if timestamp {
-				t := int64(sealers[sealer].Time)
+				t := int64(s.Time)
 				if len(format) > 0 && t > 0 {
-					output = time.Unix(t, 0).Format(format)
+					formatedTimestamp = time.Unix(t, 0).Format(format)
 				} else {
-					output = t
+					formatedTimestamp = t
 				}
-			} else {
-				output = sealers[sealer].LastBlock
 			}
-			fmt.Printf("%v: %*v\n", sealer, length, output)
+			fmt.Printf(formatStr, sealer, lastBlockLen, s.LastBlock, timestampLen, formatedTimestamp, s.Difficulty, balanceLen, s.Balance)
 		}
 	} else {
-		sealers := node.GetSignersAtBlock(blockNumber)
+		sealers := node.SealersAtBlock(blockNumber)
 		sort.Slice(sealers, func(i, j int) bool { return sealers[i] < sealers[j] })
 		if json {
 			util.PrintJson(sealers)
@@ -226,8 +270,8 @@ func autovote() {
 	util.Check(err)
 	defer node.Close()
 	util.PanicIf(!node.IsSealer(bfa.Self), "Solo los selladores pueden votar")
-	votes := node.GetVotes(latest)
-	genesisSigners := node.GetSignersAtBlock(0)
+	votes := node.Votes(latest)
+	genesisSigners := node.SealersAtBlock(0)
 	self, err := node.Coinbase()
 	util.Check(err)
 	for _, tally := range votes.Tally {
@@ -279,7 +323,7 @@ func propose() {
 	util.Check(err)
 	defer node.Close()
 	util.PanicIf(!node.IsSealer(bfa.Self), "Solo los selladores pueden votar")
-	votes := node.GetVotes(latest)
+	votes := node.Votes(latest)
 	if flags.NArg() == 0 {
 		panic("No se especificaron candidatos por los cuales votar")
 	}
@@ -310,6 +354,45 @@ func propose() {
 	}
 }
 
+func status() {
+	nodeStatus := struct {
+		Enode       string              `json:"enode"`
+		Network     uint64              `json:"network"`
+		Genesis     string              `json:"genesis"`
+		BFANetwork  bool                `json:"bfaNetwork"`
+		BFAGenesis  bool                `json:"bfaGenesis"`
+		Accounts    map[string]*big.Int `json:"accounts"`
+		Coinbase    string              `json:"coinbase"`
+		IsSealer    bool                `json:"isSealer"`
+		IsMining    bool                `json:"isMining"`
+		BlockNumber int64               `json:"blockNumber"`
+	}{
+		Accounts: make(map[string]*big.Int),
+	}
+	description = "Muestra el estado del nodo."
+	setFlags()
+	parseFlags()
+	url = updateURL(url)
+	node, err := bfa.Dial(url)
+	util.Check(err)
+	defer node.Close()
+	for _, account := range node.Accounts() {
+		nodeStatus.Accounts[account] = node.Balance(account)
+	}
+	nodeStatus.Coinbase, _ = node.Coinbase()
+	nodeStatus.BlockNumber = node.BlockNumber()
+	nodeStatus.IsSealer = node.IsSealer(bfa.Self)
+	nodeStatus.IsMining = node.IsMining()
+	nodeInfo := node.NodeInfo()
+	nodeStatus.Enode = nodeInfo.Enode
+	ethInfo := nodeInfo.Protocols["eth"].(map[string]interface{})
+	nodeStatus.Genesis = ethInfo["genesis"].(string)
+	nodeStatus.Network = uint64(ethInfo["network"].(float64))
+	nodeStatus.BFAGenesis = nodeStatus.Genesis == bfa.Genesis
+	nodeStatus.BFANetwork = nodeStatus.Network == bfa.Network
+	util.PrintJson(nodeStatus)
+}
+
 func main() {
 	var (
 		commands = map[string]func(){
@@ -317,6 +400,7 @@ func main() {
 			"sealers":   sealers,
 			"vote":      propose,
 			"autovote":  autovote,
+			"status":    status,
 		}
 		validCommands []string
 	)
@@ -326,7 +410,6 @@ func main() {
 	defer func() {
 		if err := recover(); err != nil {
 			log.Printf("Error: %s", err)
-			usage(1)
 		}
 	}()
 	if len(os.Args) > 1 {