Welcome to Bitcart SDK’s documentation!
Installing Bitcart SDK
Simply run
pip install bitcart
to install the library.
But to initialize bitcoin instance you will need
rpc_url
, rpc_login
and rpc_password
(not required, defaults
work with default ports and authentification).
For that you’ll need Bitcart daemon, so:
git clone https://github.com/bitcart/bitcart
cd bitcart
pip install -r requirements/base.txt
pip install -r requirements/daemons/btc.txt
Everywhere here coin_name
refers to coin you’re going to run or use,
COIN_NAME
is the same name but in caps.
For example if you run bitcoin, coin_name=btc, COIN_NAME=BTC
, for litecoin coin_name=ltc, COIN_NAME=LTC
.
Run pip install -r requirements/daemons/coin_name.txt
to install
requirements for daemon of coin_name
.
This will clone main Bitcart repo and install dependencies, we recommend using virtualenv for consistency(some daemons conflict one with another, so using one virtualenv per daemon is fine).
To run daemon, just start it:
python daemons/btc.py
Or, to run it in background(linux only)
python daemons/btc.py &
Note, to run a few daemons, use
python daemons/coin_name.py
for each coin_name
.
Default user is electrum and password is electrumz, it runs on http://localhost:5000.
To run daemon in other network than mainnet, set COIN_NAME_NETWORK
variable to network name (testnet, regtest).
By default, if coin supports it, lightning network is enabled.
To disable it, set COIN_NAME_LIGHTNING
to false.
For each daemon port is different.
General scheme to get your daemon url is
http://localhost:port
Where port is the port your daemon uses.
You can change port and host by using COIN_NAME_HOST
and COIN_NAME_PORT
env variables.
Default ports are starting from 5000 and increase for each daemon by 1
(in order how they were added to Bitcart).
Refer to main docs for ports information.
Bitcoin port is 5000, litecoin is 5001, etc.
So, to initialize your Bitcart instance right now,
import it and use those settings:
from bitcart import BTC
btc = BTC(xpub="your (x/y/z)pub or (x/y/z)prv or electrum seed")
All the variables are actually optional, so you can just do
btc = BTC()
and use it, but without a wallet.
To use a wallet, pass xpub like so:
btc = BTC(xpub="your x/y/zpub or x/y/zprv or electrum seed")
Xpub, xprv or electrum seed is the thing that represents your wallet.
You can get it from your wallet provider, or, for testing or not,
from here.
You can configure default user and password in conf/.env
file of cloned bitcart repo, like so:
COIN_NAME_USER=myuser
COIN_NAME_PASS=mypassword
After that you can freely use bitcart methods, refer to API docs for more information.
Bitcart SDK Events System
Introduction
To be able to listen for incoming payments, transactions, new blocks or more, you should use events system.
In SDK, each event may have one handler.
One handler may handle multiple events at once
Using event system requires wallet.
Event handler signature is the following:
def handler(event, arg1, arg2):
pass # process event
Where event
is the only required argument everywhere.
Depending on the event being handled, it may provide additional arguments. All arguments must be named exactly as event is specifying.
If using event system from APIManager, then additional required argument instance
is passed:
def handler(instance, event, arg1, arg2):
pass # process event
Also, async handlers are supported too, like so:
async def handler(event, arg1, arg2):
pass # process event, you can await here
Registering event handlers
To register an event handler, use on
decorator:
@coin.on("event")
def handler(event, arg1, arg2):
pass
You can also register a handler for multiple events, then you should mark all arguments, except for event
and instance
(if provided) optional, like so:
@coin.on(["event1", "event2"])
def handler(event, arg1=None, arg2=None, arg3=None):
pass # event argument can be used to get what event is currently being processed
Or you can use add_event_handler
method instead:
def handler(event, arg1, arg2):
pass
coin.add_event_handler("event", handler)
They work identically.
Events list
new_block
Called when a new block is mined
Additional data:
height (int): height of this block
new_transaction
Called when a new transaction on this wallet has appeared
Additional data:
tx (str): tx hash of this transaction
new_payment
Called when status of payment request has changed. (See get_request
/add_request
)
Additional data:
address (str): address related to this payment request
status (int): new status code
status_str (str): string version of new status code
Listening for updates
To receive updates, you should use one of the available event delivery methods: polling or websocket
Polling
Polling is good for quick testing, but not very good for production.
In this method SDK calls get_updates
daemon method constantly, processing any new updates received.
To use it, run:
coin.poll_updates()
It will start an infinite loop.
Websocket
Websocket is a bit harder to set up sometimes, but works better.
Instead of constantly calling daemon method to get updates, daemon will send updates when they are available via an estabilished connection.
That way, you don’t need to know your URL, you should only know daemon URL, and a channel between SDK and daemon will be set up.
To use it, run:
coin.start_websocket()
It will connect to your daemon’s /ws
endpoint, with auto-reconnecting in case of unexpected websocket close.
There may be unlimited number of websockets per wallet or not.
Under the hood, if using APIManager, daemon will send all it’s updates to SDK, and SDK will filter only the one you need.
If using coin object, daemon will only send updates about this wallet.
Manual updates processing
If you need complete control over updates delivery, you can pass updates to coin’s method directly:
coin.process_updates(updates_list)
Where updates_list
is a list of dictionaries.
Each dictionary must contain event key, and additional keys for data required for this event.
Processing updates for multiple wallets/currencies
If you need to process updates for multiple wallets/currencies, take a look at APIManager documentation
APIManager
APIManager provides an easy-to-use interface to manage multiple wallets/currencies.
Setup
Create APIManager like so:
manager = APIManager({"BTC": ["xpub1", "xpub2"], "currency2": ["xpub1", "xpub3"]})
This will load all specified wallets to the manager.
Accessing wallets
You can access wallets in a manager like so:
manager.BTC.xpub1 # access wallet <=> BTC(xpub="xpub1")
# or
manager["BTC"]["xpub1"] # same wallet, but via dict-like interface
manager["currency2"]["xpub3"] # <=> currency2(xpub="xpub3")
manager.BTC[xpub].balance() # <=> BTC(xpub=xpub).balance()
Adding new wallets to existing manager
manager.add_wallet("BTC", "xpub3") # adds wallet to currency BTC with xpub="xpub3"
manager.add_wallets("currency2", ["xpub1", "xpub2"]) # batch add
Coin objects creation utilities
manager.load_wallet("currency", "xpub") # returns currency(xpub=xpub)
manager.load_wallets("currency", ["xpub1", "xpub2"]) # returns a dict of xpub-currency(xpub=xpub)
Listening for updates on all wallets in a manager
You can register event handlers like you did before, on individual coin instances, or globally on manager object.
@manager.on("new_transaction")
def handler(instance, event, tx):
pass # instance is coin instance currently processing the event
To start connection to websocket, run:
manager.start_websocket()
API Reference
Implemented coins
BTC
BTC class supports lightning out of the box.
For lightning methods to work, it must be enabled from the daemon
(enabled by default and edited by BTC_LIGHTNING
environment variable).
If lightning is disabled, LightningDisabledError
is raised when
calling lightning methods.
- class bitcart.coins.btc.BTC(rpc_url: str | None = None, rpc_user: str | None = None, rpc_pass: str | None = None, xpub: str | None = None, proxy: str | None = None, session: ClientSession | None = None)
Bases:
Coin
,EventDelivery
- ALLOWED_EVENTS = ['new_block', 'new_transaction', 'new_payment', 'verified_tx']
- BALANCE_ATTRS = ['confirmed', 'unconfirmed', 'unmatured', 'lightning']
- EXPIRATION_KEY = 'expiry'
- RPC_PASS = 'electrumz'
- RPC_URL = 'http://localhost:5000'
- RPC_USER = 'electrum'
- add_invoice(amount: int | str | Decimal, description: str = '', expire: int | float = 15) dict
Create a lightning invoice
Create a lightning invoice and return invoice data with bolt invoice id All parameters are the same as in add_request
Example:
>>> a.add_invoice(0.5, "My invoice", 20) {'time': 1562762334, 'amount': 50000000, 'exp': 1200, 'invoice': 'lnbc500m',...
- Parameters:
self (BTC) – self
amount (AmountType) – amount to open invoice
description (str, optional) – Description of invoice. Defaults to “”.
expire (Union[int, float], optional) – The time invoice will expire in. In minutes. Defaults to 15.
- Returns:
dict – Invoice data
- add_request(amount: int | str | Decimal | None = None, description: str = '', expire: int | float = 15) dict
Add invoice
Create an invoice and request amount in BTC, it will expire by parameter provided. If expire is None, it will last forever.
Example:
>>> c.add_request(0.5, "My invoice", 20) {'time': 1562762334, 'amount': 50000000, 'exp': 1200, 'address': 'xxx',...
- Parameters:
self (BTC) – self
amount (Optional[AmountType]) – amount to open invoice. Defaults to None.
description (str, optional) – Description of invoice. Defaults to “”.
expire (Union[int, float], optional) – The time invoice will expire in. In minutes. Defaults to 15.
- Returns:
dict – Invoice data
- additional_xpub_fields: list[str] = []
- balance() dict
Get balance of wallet
Example:
>>> c.balance() {"confirmed": 0.00005, "unconfirmed": 0, "unmatured": 0}
- Returns:
dict – It should return dict of balance statuses
- close_channel(channel_id: str, force: bool = False) str
Close lightning channel
Close channel by channel_id got from open_channel, returns transaction id
- Parameters:
self (BTC) – self
channel_id (str) – channel_id from open_channel
force (bool) – Create new address beyond gap limit, if no more addresses are available.
- Returns:
str – tx_id of closed channel
- coin_name: str = 'BTC'
- connect(connection_string: str) bool
Connect to lightning node
connection string must respect format pubkey@ipaddress
- Parameters:
connection_string (str) – connection string
- Returns:
bool – True on success, False otherwise
- friendly_name: str = 'Bitcoin'
- get_address(address: str) list
Get address history
This method should return list of transaction informations for specified address
Example:
>>> c.get_address("31smpLFzLnza6k8tJbVpxXiatGjiEQDmzc") [{'tx_hash': '7854bdf4c4e27276ecc1fb8d666d6799a248f5e81bdd58b16432d1ddd1d4c332', 'height': 581878, 'tx': ...
- Parameters:
address (str) – address to get transactions for
- Returns:
list – List of transactions
- get_config(key: str) Any
Get config key
Keys are stored in electrum’s config file, check
bitcart.coins.btc.BTC.set_config()
doc for details.Example:
>>> c.get_config("x") 5
- Parameters:
self (BTC) – self
key (str) – key to get
default (Any, optional) – The value to default to when key doesn’t exist. Defaults to None.
- Returns:
Any – value of the key or default value provided
- get_invoice(rhash: str) dict
Get lightning invoice info
Get lightning invoice information by rhash got from add_invoice
Example:
>>> c.get_invoice("e34d7fb4cda66e0760fc193496c302055d0fd960cfd982432355c8bfeecd5f33") {'is_lightning': True, 'amount_BTC': Decimal('0.5'), 'timestamp': 1619273042, 'expiry': 900, ...
- Parameters:
rhash (str) – invoice rhash
- Returns:
dict – invoice data
- get_request(address: str) dict
Get invoice info
Get invoice information by address got from add_request
Example:
>>> c.get_request("1A6jnc6xQwmhsChNLcyKAQNWPcWsVYqCqJ") {'time': 1562762334, 'amount': 50000000, 'exp': 1200, 'address': '1A6jnc6xQwmhsChNLcyKAQNWPcWsVYqCqJ',...
- Parameters:
self (BTC) – self
address (str) – address of invoice
- Returns:
dict – Invoice data
- get_tx(tx: str) dict
Get transaction information
Given tx hash of transaction, return full information as dictionary
Example:
>>> c.get_tx("54604b116b28124e31d2d20bbd4561e6f8398dca4b892080bffc8c87c27762ba") {'partial': False, 'version': 2, 'segwit_ser': True, 'inputs': [{'prevout_hash': 'xxxx',...
- Parameters:
tx (str) – tx_hash
- Returns:
dict – transaction info
- help() list
Get help
Returns a list of all available RPC methods
- Returns:
list – RPC methods list
- history() dict
Get transaction history of wallet
Example:
>>> c.history() {'summary': {'end_balance': '0.', 'end_date': None, 'from_height': None, 'incoming': '0.00185511',...
- Parameters:
self (BTC) – self
- Returns:
dict – dictionary with some data, where key transactions is list of transactions
- is_eth_based = False
- list_channels() list
List all channels ever opened
Possible channel statuses: OPENING, OPEN, CLOSED, DISCONNECTED
Example:
>>> a.server.list_channels() [{'local_htlcs': {'adds': {}, 'locked_in': {}, 'settles': {}, 'fails': {}}, 'remote_htlcs': ...
- Returns:
list – list of channels
- list_peers(gossip: bool = False) list
Get a list of lightning peers
- Parameters:
gossip (bool, optional) – Whether to return peers of a gossip (one per node) or of a wallet. Defaults to False.
- Returns:
list – list of lightning peers
- lnpay(invoice: str) bool
Pay lightning invoice
Returns True on success, False otherwise
- Parameters:
invoice (str) – invoice to pay
- Returns:
bool – success or not
- property node_id: Any
Return an attribute of instance, which is of type owner.
- open_channel(node_id: str, amount: int | str | Decimal) str
Open lightning channel
Open channel with node, returns string of format txid:output_index
- Parameters:
self (BTC) – self
node_id (str) – id of node to open channel with
amount (AmountType) – amount to open channel
- Returns:
str – string of format txid:output_index
- pay_to(address: str, amount: int | str | Decimal, fee: int | str | Decimal | Callable | None = None, feerate: int | str | Decimal | None = None, broadcast: bool = True) dict | str
Pay to address
This function creates a transaction, your wallet must have sufficent balance and address must exist.
Examples:
>>> btc.pay_to("mkHS9ne12qx9pS9VojpwU5xtRd4T7X7ZUt", 0.001) '608d9af34032868fd2849723a4de9ccd874a51544a7fba879a18c847e37e577b'
>>> btc.pay_to("mkHS9ne12qx9pS9VojpwU5xtRd4T7X7ZUt",0.001, feerate=1) '23d0aec06f6ea6100ba9c6ce8a1fa5d333a6c1d39a780b5fadc4b2836d71b66f'
>>> btc.pay_to("mkHS9ne12qx9pS9VojpwU5xtRd4T7X7ZUt", 0.001, broadcast=False) {'hex': '02000000026.....', 'complete': True, 'final': False, 'name': None, 'csv_delay': 0, 'cltv_expiry': 0}
- Parameters:
self (BTC) – self
address (str) – address where to send BTC
amount (AmountType) – amount of bitcoins to send
fee (Optional[Union[AmountType, Callable]], optional) – Either a fixed fee, or a callable getting size and default fee as argument and returning fee. Defaults to None.
feerate (Optional[AmountType], optional) – A sat/byte feerate, can’t be passed together with fee argument. Defaults to None.
broadcast (bool, optional) – Whether to broadcast transaction to network. Defaults to True.
- Raises:
TypeError – if you have provided both fee and feerate
- Returns:
Union[dict, str] – tx hash of ready transaction or raw transaction, depending on broadcast argument.
- pay_to_many(outputs: Iterable[dict | tuple], fee: int | str | Decimal | Callable | None = None, feerate: int | str | Decimal | None = None, broadcast: bool = True) dict | str
Pay to multiple addresses(batch transaction)
This function creates a batch transaction, your wallet must have sufficent balance and addresses must exist. outputs parameter is either an iterable of
(address, amount)
tuples(or any iterables) or a dict with two keys: address and amount{"address": "someaddress", "amount": 0.5}
Examples:
>>> btc.pay_to_many([{"address":"mkHS9ne12qx9pS9VojpwU5xtRd4T7X7ZUt","amount":0.001}, {"address":"mv4rnyY3Su5gjcDNzbMLKBQkBicCtHUtFB","amount":0.0001}]) '60fa120d9f868a7bd03d6bbd1e225923cab0ba7a3a6b961861053c90365ed40a'
>>> btc.pay_to_many([("mkHS9ne12qx9pS9VojpwU5xtRd4T7X7ZUt",0.001), ("mv4rnyY3Su5gjcDNzbMLKBQkBicCtHUtFB",0.0001)]) 'd80f14e20af2ceaa43a8b7e15402d420246d39e235d87874f929977fb0b1cab8'
>>> btc.pay_to_many((("mkHS9ne12qx9pS9VojpwU5xtRd4T7X7ZUt",0.001), ("mkHS9ne12qx9pS9VojpwU5xtRd4T7X7ZUt",0.001)), feerate=1) '0a6611876e04a6f2742eac02d4fac4c242dda154d85f0d547bbac1a33dbbbe34'
>>> btc.pay_to_many([("mkHS9ne12qx9pS9VojpwU5xtRd4T7X7ZUt",0.001), ("mv4rnyY3Su5gjcDNzbMLKBQkBicCtHUtFB",0.0001)], broadcast=False) {'hex': '0200000...', 'complete': True, 'final': False}
- Parameters:
self (BTC) – self
outputs (Iterable[Union[dict, tuple]]) – An iterable with dictionary or iterable as the item
fee (Optional[Union[AmountType, Callable]], optional) – Either a fixed fee, or a callable getting size and default fee as argument and returning fee. Defaults to None.
feerate (Optional[AmountType], optional) – A sat/byte feerate, can’t be passed together with fee argument. Defaults to None.
broadcast (bool, optional) – Whether to broadcast transaction to network. Defaults to True.
- Raises:
TypeError – if you have provided both fee and feerate
- Returns:
Union[dict, str] – tx hash of ready transaction or raw transaction, depending on broadcast argument.
- poll_updates(timeout: int | float = 1) None
Poll updates
Poll daemon for new transactions in wallet, this will block forever in while True loop checking for new transactions
Example can be found on main page of docs
- Parameters:
self (BTC) – self
timeout (Union[int, float], optional) – seconds to wait before requesting transactions again. Defaults to 1.
- Returns:
None – This function runs forever
- process_updates(updates: Iterable[dict], *args: Any, pass_instance: bool = False, **kwargs: Any) None
- set_config(key: str, value: Any) bool
Set config key to specified value
It sets the config value in electrum’s config store, usually $HOME/.electrum/config
You can set any keys and values using this function(as long as JSON serializable), and some are used to configure underlying electrum daemon.
Example:
>>> c.set_config("x", 5) True
- Parameters:
self (BTC) – self
key (str) – key to set
value (Any) – value to set
- Returns:
bool – True on success, False otherwise
- property spec: Any
Return an attribute of instance, which is of type owner.
- start_websocket(reconnect_callback: Callable | None = None, force_connect: bool = False, auto_reconnect: bool = True) None
Start a websocket connection to daemon
- Parameters:
reconnect_callback (Optional[Callable], optional) – Callback to be called right after each succesful connection. Defaults to None.
force_connect (bool, optional) – Whether to try reconnecting even on first failure (handshake) to daemon. Defaults to False.
auto_reconnect (bool, optional) – Whether to enable auto-reconnecting on websocket closing. Defaults to True.
- validate_key(key: str, *args: Any, **kwargs: Any) bool
Validate whether provided key is valid to restore a wallet
If the key is x/y/z pub/prv or electrum seed at the network daemon is running at, then it would be valid(True), else False
Examples:
>>> c.validate_key("test") False
>>> c.validate_key("your awesome electrum seed") True
>>> c.validate_key("x/y/z pub/prv here") True
- Parameters:
self (BTC) – self
key (str) – key to check
- Returns:
bool – Whether the key is valid or not
- xpub_name: str = 'Xpub'
BCH
BCH supports Schnorr signatures, they are enabled out of the box
- class bitcart.coins.bch.BCH(rpc_url: str | None = None, rpc_user: str | None = None, rpc_pass: str | None = None, xpub: str | None = None, proxy: str | None = None, session: ClientSession | None = None)
Bases:
BTC
- AMOUNT_FIELD = 'amount (BCH)'
- EXPIRATION_KEY = 'expiration'
- RPC_URL = 'http://localhost:5004'
- coin_name: str = 'BCH'
- event_handlers: dict[str, Callable]
- friendly_name: str = 'Bitcoin Cash'
- history() dict
Get transaction history of wallet
Example:
>>> c.history() {'summary': {'end_balance': '0.', 'end_date': None, 'from_height': None, 'incoming': '0.00185511',...
- Parameters:
self (BTC) – self
- Returns:
dict – dictionary with some data, where key transactions is list of transactions
- property node_id: Any
Return an attribute of instance, which is of type owner.
- server: RPCProxy
- property spec: Any
Return an attribute of instance, which is of type owner.
- xpub: str | None
XMR
XMR support is based on our custom daemon implementation which tries to follow electrum APIs as closely as possible
- class bitcart.coins.xmr.XMR(rpc_url: str | None = None, rpc_user: str | None = None, rpc_pass: str | None = None, xpub: str | None = None, proxy: str | None = None, session: ClientSession | None = None)
Bases:
ETH
- RPC_URL = 'http://localhost:5011'
- additional_xpub_fields: list[str] = ['address']
- coin_name: str = 'XMR'
- event_handlers: dict[str, Callable]
- friendly_name: str = 'Monero'
- get_address(*args: Any, **kwargs: Any) NoReturn
Get address history
This method should return list of transaction informations for specified address
Example:
>>> c.get_address("31smpLFzLnza6k8tJbVpxXiatGjiEQDmzc") [{'tx_hash': '7854bdf4c4e27276ecc1fb8d666d6799a248f5e81bdd58b16432d1ddd1d4c332', 'height': 581878, 'tx': ...
- Parameters:
address (str) – address to get transactions for
- Returns:
list – List of transactions
- history() dict
Get transaction history of wallet
Example:
>>> c.history() {'summary': {'end_balance': '0.', 'end_date': None, 'from_height': None, 'incoming': '0.00185511',...
- Parameters:
self (BTC) – self
- Returns:
dict – dictionary with some data, where key transactions is list of transactions
- property node_id: Any
Return an attribute of instance, which is of type owner.
- pay_to_many(*args: Any, **kwargs: Any) NoReturn
Pay to multiple addresses(batch transaction)
This function creates a batch transaction, your wallet must have sufficent balance and addresses must exist. outputs parameter is either an iterable of
(address, amount)
tuples(or any iterables) or a dict with two keys: address and amount{"address": "someaddress", "amount": 0.5}
Examples:
>>> btc.pay_to_many([{"address":"mkHS9ne12qx9pS9VojpwU5xtRd4T7X7ZUt","amount":0.001}, {"address":"mv4rnyY3Su5gjcDNzbMLKBQkBicCtHUtFB","amount":0.0001}]) '60fa120d9f868a7bd03d6bbd1e225923cab0ba7a3a6b961861053c90365ed40a'
>>> btc.pay_to_many([("mkHS9ne12qx9pS9VojpwU5xtRd4T7X7ZUt",0.001), ("mv4rnyY3Su5gjcDNzbMLKBQkBicCtHUtFB",0.0001)]) 'd80f14e20af2ceaa43a8b7e15402d420246d39e235d87874f929977fb0b1cab8'
>>> btc.pay_to_many((("mkHS9ne12qx9pS9VojpwU5xtRd4T7X7ZUt",0.001), ("mkHS9ne12qx9pS9VojpwU5xtRd4T7X7ZUt",0.001)), feerate=1) '0a6611876e04a6f2742eac02d4fac4c242dda154d85f0d547bbac1a33dbbbe34'
>>> btc.pay_to_many([("mkHS9ne12qx9pS9VojpwU5xtRd4T7X7ZUt",0.001), ("mv4rnyY3Su5gjcDNzbMLKBQkBicCtHUtFB",0.0001)], broadcast=False) {'hex': '0200000...', 'complete': True, 'final': False}
- Parameters:
self (BTC) – self
outputs (Iterable[Union[dict, tuple]]) – An iterable with dictionary or iterable as the item
fee (Optional[Union[AmountType, Callable]], optional) – Either a fixed fee, or a callable getting size and default fee as argument and returning fee. Defaults to None.
feerate (Optional[AmountType], optional) – A sat/byte feerate, can’t be passed together with fee argument. Defaults to None.
broadcast (bool, optional) – Whether to broadcast transaction to network. Defaults to True.
- Raises:
TypeError – if you have provided both fee and feerate
- Returns:
Union[dict, str] – tx hash of ready transaction or raw transaction, depending on broadcast argument.
- server: RPCProxy
- property spec: Any
Return an attribute of instance, which is of type owner.
- xpub: str | None
- xpub_name: str = 'Secret viewkey'
ETH
ETH support is based on our custom daemon implementation which tries to follow electrum APIs as closely as possible
- class bitcart.coins.eth.ETH(rpc_url: str | None = None, rpc_user: str | None = None, rpc_pass: str | None = None, xpub: str | None = None, proxy: str | None = None, session: ClientSession | None = None)
Bases:
BTC
- ALLOWED_EVENTS = ['new_block', 'new_transaction', 'new_payment']
- EXPIRATION_KEY = 'expiration'
- RPC_URL = 'http://localhost:5002'
- coin_name: str = 'ETH'
- event_handlers: dict[str, Callable]
- friendly_name: str = 'Ethereum'
- get_address(*args: Any, **kwargs: Any) NoReturn
Get address history
This method should return list of transaction informations for specified address
Example:
>>> c.get_address("31smpLFzLnza6k8tJbVpxXiatGjiEQDmzc") [{'tx_hash': '7854bdf4c4e27276ecc1fb8d666d6799a248f5e81bdd58b16432d1ddd1d4c332', 'height': 581878, 'tx': ...
- Parameters:
address (str) – address to get transactions for
- Returns:
list – List of transactions
- history() dict
Get transaction history of wallet
Example:
>>> c.history() {'summary': {'end_balance': '0.', 'end_date': None, 'from_height': None, 'incoming': '0.00185511',...
- Parameters:
self (BTC) – self
- Returns:
dict – dictionary with some data, where key transactions is list of transactions
- is_eth_based = True
- property node_id: Any
Return an attribute of instance, which is of type owner.
- pay_to_many(*args: Any, **kwargs: Any) NoReturn
Pay to multiple addresses(batch transaction)
This function creates a batch transaction, your wallet must have sufficent balance and addresses must exist. outputs parameter is either an iterable of
(address, amount)
tuples(or any iterables) or a dict with two keys: address and amount{"address": "someaddress", "amount": 0.5}
Examples:
>>> btc.pay_to_many([{"address":"mkHS9ne12qx9pS9VojpwU5xtRd4T7X7ZUt","amount":0.001}, {"address":"mv4rnyY3Su5gjcDNzbMLKBQkBicCtHUtFB","amount":0.0001}]) '60fa120d9f868a7bd03d6bbd1e225923cab0ba7a3a6b961861053c90365ed40a'
>>> btc.pay_to_many([("mkHS9ne12qx9pS9VojpwU5xtRd4T7X7ZUt",0.001), ("mv4rnyY3Su5gjcDNzbMLKBQkBicCtHUtFB",0.0001)]) 'd80f14e20af2ceaa43a8b7e15402d420246d39e235d87874f929977fb0b1cab8'
>>> btc.pay_to_many((("mkHS9ne12qx9pS9VojpwU5xtRd4T7X7ZUt",0.001), ("mkHS9ne12qx9pS9VojpwU5xtRd4T7X7ZUt",0.001)), feerate=1) '0a6611876e04a6f2742eac02d4fac4c242dda154d85f0d547bbac1a33dbbbe34'
>>> btc.pay_to_many([("mkHS9ne12qx9pS9VojpwU5xtRd4T7X7ZUt",0.001), ("mv4rnyY3Su5gjcDNzbMLKBQkBicCtHUtFB",0.0001)], broadcast=False) {'hex': '0200000...', 'complete': True, 'final': False}
- Parameters:
self (BTC) – self
outputs (Iterable[Union[dict, tuple]]) – An iterable with dictionary or iterable as the item
fee (Optional[Union[AmountType, Callable]], optional) – Either a fixed fee, or a callable getting size and default fee as argument and returning fee. Defaults to None.
feerate (Optional[AmountType], optional) – A sat/byte feerate, can’t be passed together with fee argument. Defaults to None.
broadcast (bool, optional) – Whether to broadcast transaction to network. Defaults to True.
- Raises:
TypeError – if you have provided both fee and feerate
- Returns:
Union[dict, str] – tx hash of ready transaction or raw transaction, depending on broadcast argument.
- server: RPCProxy
- property spec: Any
Return an attribute of instance, which is of type owner.
- xpub: str | None
- xpub_name: str = 'Address'
BNB
BNB support is based on our custom daemon implementation which tries to follow electrum APIs as closely as possible
- class bitcart.coins.bnb.BNB(rpc_url: str | None = None, rpc_user: str | None = None, rpc_pass: str | None = None, xpub: str | None = None, proxy: str | None = None, session: ClientSession | None = None)
Bases:
ETH
- RPC_URL = 'http://localhost:5006'
- coin_name: str = 'BNB'
- event_handlers: dict[str, Callable]
- friendly_name: str = 'Binance Smart Chain'
- property node_id: Any
Return an attribute of instance, which is of type owner.
- server: RPCProxy
- property spec: Any
Return an attribute of instance, which is of type owner.
- xpub: str | None
SmartBCH
SmartBCH support is based on our custom daemon implementation which tries to follow electrum APIs as closely as possible
- class bitcart.coins.sbch.SBCH(rpc_url: str | None = None, rpc_user: str | None = None, rpc_pass: str | None = None, xpub: str | None = None, proxy: str | None = None, session: ClientSession | None = None)
Bases:
ETH
- RPC_URL = 'http://localhost:5007'
- coin_name: str = 'SBCH'
- event_handlers: dict[str, Callable]
- friendly_name: str = 'Smart Bitcoin Cash'
- property node_id: Any
Return an attribute of instance, which is of type owner.
- server: RPCProxy
- property spec: Any
Return an attribute of instance, which is of type owner.
- xpub: str | None
Polygon (MATIC)
Polygon (MATIC) support is based on our custom daemon implementation which tries to follow electrum APIs as closely as possible
- class bitcart.coins.matic.MATIC(rpc_url: str | None = None, rpc_user: str | None = None, rpc_pass: str | None = None, xpub: str | None = None, proxy: str | None = None, session: ClientSession | None = None)
Bases:
ETH
- RPC_URL = 'http://localhost:5008'
- coin_name: str = 'MATIC'
- event_handlers: dict[str, Callable]
- friendly_name: str = 'Polygon'
- property node_id: Any
Return an attribute of instance, which is of type owner.
- server: RPCProxy
- property spec: Any
Return an attribute of instance, which is of type owner.
- xpub: str | None
TRON (TRX)
TRON (TRX) support is based on our custom daemon implementation which tries to follow electrum APIs as closely as possible
- class bitcart.coins.trx.TRX(rpc_url: str | None = None, rpc_user: str | None = None, rpc_pass: str | None = None, xpub: str | None = None, proxy: str | None = None, session: ClientSession | None = None)
Bases:
ETH
- RPC_URL = 'http://localhost:5009'
- coin_name: str = 'TRX'
- event_handlers: dict[str, Callable]
- friendly_name: str = 'Tron'
- property node_id: Any
Return an attribute of instance, which is of type owner.
- server: RPCProxy
- property spec: Any
Return an attribute of instance, which is of type owner.
- xpub: str | None
XRG
XRG supports Schnorr signatures, they are enabled out of the box
- class bitcart.coins.xrg.XRG(rpc_url: str | None = None, rpc_user: str | None = None, rpc_pass: str | None = None, xpub: str | None = None, proxy: str | None = None, session: ClientSession | None = None)
Bases:
BCH
- AMOUNT_FIELD = 'amount (XRG)'
- RPC_URL = 'http://localhost:5005'
- coin_name: str = 'XRG'
- event_handlers: dict[str, Callable]
- friendly_name: str = 'Ergon'
- property node_id: Any
Return an attribute of instance, which is of type owner.
- server: RPCProxy
- property spec: Any
Return an attribute of instance, which is of type owner.
- xpub: str | None
LTC
LTC class supports lightning out of the box.
For lightning methods to work, it must be enabled from the daemon
(enabled by default and edited by LTC_LIGHTNING
environment variable).
If lightning is disabled, LightningDisabledError
is raised when
calling lightning methods.
- class bitcart.coins.ltc.LTC(rpc_url: str | None = None, rpc_user: str | None = None, rpc_pass: str | None = None, xpub: str | None = None, proxy: str | None = None, session: ClientSession | None = None)
Bases:
BTC
- RPC_URL = 'http://localhost:5001'
- coin_name: str = 'LTC'
- event_handlers: dict[str, Callable]
- friendly_name: str = 'Litecoin'
- property node_id: Any
Return an attribute of instance, which is of type owner.
- server: RPCProxy
- property spec: Any
Return an attribute of instance, which is of type owner.
- xpub: str | None
BSTY
BSTY class supports lightning out of the box.
For lightning methods to work, it must be enabled from the daemon
(enabled by default and edited by BSTY_LIGHTNING
environment variable).
If lightning is disabled, LightningDisabledError
is raised when
calling lightning methods.
- class bitcart.coins.bsty.BSTY(rpc_url: str | None = None, rpc_user: str | None = None, rpc_pass: str | None = None, xpub: str | None = None, proxy: str | None = None, session: ClientSession | None = None)
Bases:
BTC
- RPC_URL = 'http://localhost:5003'
- coin_name: str = 'BSTY'
- event_handlers: dict[str, Callable]
- friendly_name: str = 'GlobalBoost'
- property node_id: Any
Return an attribute of instance, which is of type owner.
- server: RPCProxy
- property spec: Any
Return an attribute of instance, which is of type owner.
- xpub: str | None
GRS
GRS class supports lightning out of the box.
For lightning methods to work, it must be enabled from the daemon
(enabled by default and edited by GRS_LIGHTNING
environment variable).
If lightning is disabled, LightningDisabledError
is raised when
calling lightning methods.
- class bitcart.coins.grs.GRS(rpc_url: str | None = None, rpc_user: str | None = None, rpc_pass: str | None = None, xpub: str | None = None, proxy: str | None = None, session: ClientSession | None = None)
Bases:
BTC
- RPC_URL = 'http://localhost:5010'
- coin_name: str = 'GRS'
- event_handlers: dict[str, Callable]
- friendly_name: str = 'Groestlcoin'
- property node_id: Any
Return an attribute of instance, which is of type owner.
- server: RPCProxy
- property spec: Any
Return an attribute of instance, which is of type owner.
- xpub: str | None
Utilities
- bitcart.utils.bitcoins(amount: int) Decimal
Convert amount from satoshis to bitcoins
- Parameters:
amount (int) – amount in satoshis
- Returns:
Decimal – amount in bitcoins
- async bitcart.utils.call_universal(func: Callable, *args: Any, **kwargs: Any) Any
Call a function: async or sync one. All passed arguments are passed to the function too
- Parameters:
func (Callable) – a function to call: either sync or async one
- Returns:
Any – function execution result
- bitcart.utils.convert_amount_type(amount: str | Decimal) Decimal
Convert amount from str to Decimal
- Parameters:
amount (Union[str, Decimal]) – amount
- Returns:
Decimal
- bitcart.utils.json_encode(obj: Any) Any
json.dumps supporting Decimals
- Parameters:
obj (Any) – any object
- Returns:
Any – return value of json.dumps
- bitcart.utils.satoshis(amount: str | Decimal) int
Convert amount from bitcoins to satoshis
- Parameters:
amount (Union[str, Decimal]) – bitcoin amount
- Returns:
int – same amount in satoshis
Bitcart is a platform to simplify cryptocurrencies adaptation. This SDK is part of Bitcart. Using this SDK you can easily connect to Bitcart daemon and code scripts around it easily.
Behold, the power of Bitcart:
from bitcart import BTC
btc = BTC(xpub="your (x/y/z)pub or (x/y/z)prv or electrum seed")
@btc.on("new_transaction")
def callback_func(event, tx):
print(event)
print(tx)
btc.poll_updates()
This simple script will listen for any new transaction on your wallet’s addresses and print information about them like so:

And if you add print(btc.get_tx(tx))
it would print
full information about every transaction, too!
To run this script, refer to installation section. For examples of usage, check examples directory in github repository.
Supported coins list(⚡ means lightning is supported):
Bitcoin (⚡)
Bitcoin Cash
Monero
Ethereum
Binance coin (BNB)
SmartBCH
Polygon (MATIC)
Tron (TRX)
Ergon
Litecoin (⚡)
Globalboost (⚡)
Groestlcoin (⚡)
To use proxy, install optional dependencies:
pip install bitcart[proxy]
HTTP, SOCKS4 and SOCKS5 proxies supported.
To use, pass proxy url to coin constructor:
btc = BTC(proxy="socks5://localhost:9050")