---
tags: Client library
---
# Getting Start with Pyband 🐍
## Installation
The library is available on [Pypl](https://pypi.org/project/pyband/)
```
pip install pyband
```
## Example Usage
### Making a request
Making a request can be done by the following steps.
**Step 1:** Import `pyband` and put `grpc_url` as a parameter. Then initialize the client instance. Every method in client module can now be used.
``` python
from pyband.client import Client
def main():
# Step 1
grpc_url = "rpc-laozi-testnet2.bandchain.org:9090"
c = Client(grpc_url)
if __name__ == "__main__":
main()
```
**Step 2:** The sender address is required for sending the transaction, so we have to initialize the address first. Start with importing the `PrivateKey` from wallet module to get the private key. In this example, we will get it from our test mnemonic, for example,`test`
``` python
import os
from pyband.client import Client
from pyband.wallet import PrivateKey
def main():
# Step 1
grpc_url = "rpc-laozi-testnet2.bandchain.org:9090"
c = Client(grpc_url)
#Step 2
MNEMONIC = os.getenv("MNEMONIC")
private_key = PrivateKey.from_mnemonic(MNEMONIC)
public_key = private_key.to_public_key()
sender_addr = public_key.to_address()
sender = sender_addr.to_acc_bech32()
if __name__ == "__main__":
main()
```
After that, we will transform the private key to the public key, public key to address, and address with a type of `Address` to an address with a type of `str`.
**Step 3:** Before constructing a transaction, additional information is needed.
First let us see what does transaction required.
- messages
- sequence
- account_num
- chain_id
- fee
- gas
- memo
so now let us get those additional information.
#### Messages
In this example, we will use `MsgRequestData` with the following parameters as our message.
- **oracle_script_id** `<int>`: The oracle script ID.
- **calldata** `<bytes>`: The calldata from a request.
- **ask_count** `<int>`: The number of validator required to process this transaction.
- **min_count** `<int>`: The minimum number of validator required to process this transaction.
- **client_id** `<str>`: Name of the client (can be any name or an empty string).
- **fee_limit** `<[Coin]>`: The fee limit.
- **prepare_gas** `<int>`: The amount of gas used in preparation stage.
- **execute_gas** `<int>`: The amount of gas used in execution stage.
- **sender** `<str>`: The sender address.
``` python
# from pyband.proto.oracle.v1.tx_pb2 import MsgRequestData
request_msg = MsgRequestData(
oracle_script_id=37,
calldata=bytes.fromhex("0000000200000003425443000000034554480000000000000064"),
ask_count=4,
min_count=3,
client_id="BandProtocol",
fee_limit=[Coin(amount="100", denom="uband")],
prepare_gas=50000,
execute_gas=200000,
sender=sender,
)
```
Besides from inputting bytes to calldata, oracle binay encoding (obi) can also be used.
``` python
# from pyband.obi import PyObi
obi = PyObi("{symbols:[string],multiplier:u64}/{rates:[u64]}")
calldata = obi.encode({"symbols": ["ETH"], "multiplier": 100})
```
The message can be in any message listed [here](https://github.com/bandprotocol/cosmoscan/blob/1f55f3c88b462fc02d0b2c9fca1391a5daa3bdc6/src/subscriptions/TxSub.re#L1032). Please note that our message should be imported from the generated protobuf files.
#### Sequence and Account Number
Sequence and account number can be retrieved from calling `get_account(address)` in client module.
``` python
account = c.get_account(sender)
account_num = account.account_number
sequence = account.sequence
```
#### Fee
Fee can be created by using `Coin` from the generated protobuf file.
``` python
# from pyband.proto.cosmos.tx.v1beta1.tx_pb2 import Fee
# from pyband.proto.cosmos.base.v1beta1.coin_pb2 import Coin
fee = [Coin(amount="0", denom="uband")]
```
**Step 4:** Now it is time to construct a `Transaction` from transaction module.
``` python
import os
from pyband.client import Client
from pyband.transaction import Transaction
from pyband.wallet import PrivateKey
from pyband.proto.cosmos.base.v1beta1.coin_pb2 import Coin
from pyband.proto.oracle.v1.tx_pb2 import MsgRequestData
def main():
# Step 1
grpc_url = "rpc-laozi-testnet2.bandchain.org:9090"
c = Client(grpc_url)
# Step 2
MNEMONIC = os.getenv("MNEMONIC")
private_key = PrivateKey.from_mnemonic(MNEMONIC)
public_key = private_key.to_public_key()
sender_addr = public_key.to_address()
sender = sender_addr.to_acc_bech32()
# Step 3
request_msg = MsgRequestData(
oracle_script_id=37,
calldata=bytes.fromhex("0000000200000003425443000000034554480000000000000064"),
ask_count=4,
min_count=3,
client_id="BandProtocol",
fee_limit=[Coin(amount="100", denom="uband")],
prepare_gas=50000,
execute_gas=200000,
sender=sender,
)
account = c.get_account(sender)
account_num = account.account_number
sequence = account.sequence
fee = [Coin(amount="0", denom="uband")]
chain_id = c.get_chain_id()
# Step 4
txn = (
Transaction()
.with_messages(request_msg)
.with_sequence(sequence)
.with_account_num(account_num)
.with_chain_id(chain_id)
.with_gas(2000000)
.with_fee(fee)
.with_memo("")
)
if __name__ == "__main__":
main()
```
**Step 5:** Preparing the transaction before sending
Call `get_sign_doc` to get the transaction that is ready to sign, then we will get the signature by signing the transaction.
After that, we will get the raw transaction by calling `get_tx_data` and put the signature as parameters.
``` python
sign_doc = txn.get_sign_doc(public_key)
# Need to serialize sign_doc of type cosmos_tx_type.SignDoc to string
signature = private_key.sign(sign_doc.SerializeToString())
tx_raw_bytes = txn.get_tx_data(signature, public_key)
```
**Step 6:** After we got raw transaction, transaction can now be sent.
There are 3 modes for sending the transaction. Block mode is chosen for this example, we can call `send_tx_block_mode` with raw transaction as parameter.
``` python
import os
from pyband.client import Client
from pyband.transaction import Transaction
from pyband.wallet import PrivateKey
from pyband.proto.cosmos.base.v1beta1.coin_pb2 import Coin
from pyband.proto.oracle.v1.tx_pb2 import MsgRequestData
from google.protobuf.json_format import MessageToJson
def main():
# Step 1
grpc_url = "rpc-laozi-testnet2.bandchain.org:9090"
c = Client(grpc_url)
# Step 2
MNEMONIC = os.getenv("MNEMONIC")
private_key = PrivateKey.from_mnemonic(MNEMONIC)
public_key = private_key.to_public_key()
sender_addr = public_key.to_address()
sender = sender_addr.to_acc_bech32()
# Step 3
request_msg = MsgRequestData(
oracle_script_id=37,
calldata=bytes.fromhex("0000000200000003425443000000034554480000000000000064"),
ask_count=4,
min_count=3,
client_id="BandProtocol",
fee_limit=[Coin(amount="100", denom="uband")],
prepare_gas=50000,
execute_gas=200000,
sender=sender,
)
account = c.get_account(sender)
account_num = account.account_number
sequence = account.sequence
fee = [Coin(amount="0", denom="uband")]
chain_id = c.get_chain_id()
# Step 4
txn = (
Transaction()
.with_messages(request_msg)
.with_sequence(sequence)
.with_account_num(account_num)
.with_chain_id(chain_id)
.with_gas(2000000)
.with_fee(fee)
.with_memo("")
)
# Step 5
sign_doc = txn.get_sign_doc(public_key)
signature = private_key.sign(sign_doc.SerializeToString())
tx_raw_bytes = txn.get_tx_data(signature, public_key)
# Step 6
tx_block = c.send_tx_block_mode(tx_raw_bytes)
print(MessageToJson(tx_block))
if __name__ == "__main__":
main()
```
The result should look like this.
```
{"height":"603247","txhash":"587FF6D48E5CB8A23715389FE3CAC10262777B395E4D0C554916127461F63446","data":"0A090A0772657175657374","rawLog":"[{\"events\":[{\"type\":\"message\",\"attributes\":[{\"key\":\"action\",\"value\":\"request\"}]},{\"type\":\"raw_request\",\"attributes\":[{\"key\":\"data_source_id\",\"value\":\"61\"},{\"key\":\"data_source_hash\",\"value\":\"07be7bd61667327aae10b7a13a542c7dfba31b8f4c52b0b60bf9c7b11b1a72ef\"},{\"key\":\"external_id\",\"value\":\"6\"},{\"key\":\"calldata\",\"value\":\"BTC ETH\"},{\"key\":\"fee\"},{\"key\":\"data_source_id\",\"value\":\"57\"},{\"key\":\"data_source_hash\",\"value\":\"61b369daa5c0918020a52165f6c7662d5b9c1eee915025cb3d2b9947a26e48c7\"},{\"key\":\"external_id\",\"value\":\"0\"},{\"key\":\"calldata\",\"value\":\"BTC ETH\"},{\"key\":\"fee\"},{\"key\":\"data_source_id\",\"value\":\"62\"},{\"key\":\"data_source_hash\",\"value\":\"107048da9dbf7960c79fb20e0585e080bb9be07d42a1ce09c5479bbada8d0289\"},{\"key\":\"external_id\",\"value\":\"3\"},{\"key\":\"calldata\",\"value\":\"BTC ETH\"},{\"key\":\"fee\"},{\"key\":\"data_source_id\",\"value\":\"60\"},{\"key\":\"data_source_hash\",\"value\":\"2e588de76a58338125022bc42b460072300aebbcc4acaf55f91755c1c1799bac\"},{\"key\":\"external_id\",\"value\":\"5\"},{\"key\":\"calldata\",\"value\":\"huobipro BTC ETH\"},{\"key\":\"fee\"},{\"key\":\"data_source_id\",\"value\":\"59\"},{\"key\":\"data_source_hash\",\"value\":\"5c011454981c473af3bf6ef93c76b36bfb6cc0ce5310a70a1ba569de3fc0c15d\"},{\"key\":\"external_id\",\"value\":\"2\"},{\"key\":\"calldata\",\"value\":\"BTC ETH\"},{\"key\":\"fee\"},{\"key\":\"data_source_id\",\"value\":\"60\"},{\"key\":\"data_source_hash\",\"value\":\"2e588de76a58338125022bc42b460072300aebbcc4acaf55f91755c1c1799bac\"},{\"key\":\"external_id\",\"value\":\"4\"},{\"key\":\"calldata\",\"value\":\"binance BTC ETH\"},{\"key\":\"fee\"},{\"key\":\"data_source_id\",\"value\":\"60\"},{\"key\":\"data_source_hash\",\"value\":\"2e588de76a58338125022bc42b460072300aebbcc4acaf55f91755c1c1799bac\"},{\"key\":\"external_id\",\"value\":\"9\"},{\"key\":\"calldata\",\"value\":\"bittrex BTC ETH\"},{\"key\":\"fee\"},{\"key\":\"data_source_id\",\"value\":\"60\"},{\"key\":\"data_source_hash\",\"value\":\"2e588de76a58338125022bc42b460072300aebbcc4acaf55f91755c1c1799bac\"},{\"key\":\"external_id\",\"value\":\"7\"},{\"key\":\"calldata\",\"value\":\"kraken BTC ETH\"},{\"key\":\"fee\"},{\"key\":\"data_source_id\",\"value\":\"60\"},{\"key\":\"data_source_hash\",\"value\":\"2e588de76a58338125022bc42b460072300aebbcc4acaf55f91755c1c1799bac\"},{\"key\":\"external_id\",\"value\":\"8\"},{\"key\":\"calldata\",\"value\":\"bitfinex BTC ETH\"},{\"key\":\"fee\"},{\"key\":\"data_source_id\",\"value\":\"58\"},{\"key\":\"data_source_hash\",\"value\":\"7e6759fade717a06fb643392bfde837bfc3437da2ded54feed706e6cd35de461\"},{\"key\":\"external_id\",\"value\":\"1\"},{\"key\":\"calldata\",\"value\":\"BTC ETH\"},{\"key\":\"fee\"}]},{\"type\":\"request\",\"attributes\":[{\"key\":\"id\",\"value\":\"306633\"},{\"key\":\"client_id\",\"value\":\"BandProtocol\"},{\"key\":\"oracle_script_id\",\"value\":\"37\"},{\"key\":\"calldata\",\"value\":\"0000000200000003425443000000034554480000000000000064\"},{\"key\":\"ask_count\",\"value\":\"4\"},{\"key\":\"min_count\",\"value\":\"3\"},{\"key\":\"gas_used\",\"value\":\"111048\"},{\"key\":\"total_fees\"},{\"key\":\"validator\",\"value\":\"bandvaloper1zl5925n5u24njn9axpygz8lhjl5a8v4cpkzx5g\"},{\"key\":\"validator\",\"value\":\"bandvaloper17n5rmujk78nkgss7tjecg4nfzn6geg4cqtyg3u\"},{\"key\":\"validator\",\"value\":\"bandvaloper1p46uhvdk8vr829v747v85hst3mur2dzlhfemmz\"},{\"key\":\"validator\",\"value\":\"bandvaloper1ldtwjzsplhxzhrg3k5hhr8v0qterv05vpdxp9f\"}]}]}]","logs":[{"events":[{"type":"message","attributes":[{"key":"action","value":"request"}]},{"type":"raw_request","attributes":[{"key":"data_source_id","value":"61"},{"key":"data_source_hash","value":"07be7bd61667327aae10b7a13a542c7dfba31b8f4c52b0b60bf9c7b11b1a72ef"},{"key":"external_id","value":"6"},{"key":"calldata","value":"BTC ETH"},{"key":"fee"},{"key":"data_source_id","value":"57"},{"key":"data_source_hash","value":"61b369daa5c0918020a52165f6c7662d5b9c1eee915025cb3d2b9947a26e48c7"},{"key":"external_id","value":"0"},{"key":"calldata","value":"BTC ETH"},{"key":"fee"},{"key":"data_source_id","value":"62"},{"key":"data_source_hash","value":"107048da9dbf7960c79fb20e0585e080bb9be07d42a1ce09c5479bbada8d0289"},{"key":"external_id","value":"3"},{"key":"calldata","value":"BTC ETH"},{"key":"fee"},{"key":"data_source_id","value":"60"},{"key":"data_source_hash","value":"2e588de76a58338125022bc42b460072300aebbcc4acaf55f91755c1c1799bac"},{"key":"external_id","value":"5"},{"key":"calldata","value":"huobipro BTC ETH"},{"key":"fee"},{"key":"data_source_id","value":"59"},{"key":"data_source_hash","value":"5c011454981c473af3bf6ef93c76b36bfb6cc0ce5310a70a1ba569de3fc0c15d"},{"key":"external_id","value":"2"},{"key":"calldata","value":"BTC ETH"},{"key":"fee"},{"key":"data_source_id","value":"60"},{"key":"data_source_hash","value":"2e588de76a58338125022bc42b460072300aebbcc4acaf55f91755c1c1799bac"},{"key":"external_id","value":"4"},{"key":"calldata","value":"binance BTC ETH"},{"key":"fee"},{"key":"data_source_id","value":"60"},{"key":"data_source_hash","value":"2e588de76a58338125022bc42b460072300aebbcc4acaf55f91755c1c1799bac"},{"key":"external_id","value":"9"},{"key":"calldata","value":"bittrex BTC ETH"},{"key":"fee"},{"key":"data_source_id","value":"60"},{"key":"data_source_hash","value":"2e588de76a58338125022bc42b460072300aebbcc4acaf55f91755c1c1799bac"},{"key":"external_id","value":"7"},{"key":"calldata","value":"kraken BTC ETH"},{"key":"fee"},{"key":"data_source_id","value":"60"},{"key":"data_source_hash","value":"2e588de76a58338125022bc42b460072300aebbcc4acaf55f91755c1c1799bac"},{"key":"external_id","value":"8"},{"key":"calldata","value":"bitfinex BTC ETH"},{"key":"fee"},{"key":"data_source_id","value":"58"},{"key":"data_source_hash","value":"7e6759fade717a06fb643392bfde837bfc3437da2ded54feed706e6cd35de461"},{"key":"external_id","value":"1"},{"key":"calldata","value":"BTC ETH"},{"key":"fee"}]},{"type":"request","attributes":[{"key":"id","value":"306633"},{"key":"client_id","value":"BandProtocol"},{"key":"oracle_script_id","value":"37"},{"key":"calldata","value":"0000000200000003425443000000034554480000000000000064"},{"key":"ask_count","value":"4"},{"key":"min_count","value":"3"},{"key":"gas_used","value":"111048"},{"key":"total_fees"},{"key":"validator","value":"bandvaloper1zl5925n5u24njn9axpygz8lhjl5a8v4cpkzx5g"},{"key":"validator","value":"bandvaloper17n5rmujk78nkgss7tjecg4nfzn6geg4cqtyg3u"},{"key":"validator","value":"bandvaloper1p46uhvdk8vr829v747v85hst3mur2dzlhfemmz"},{"key":"validator","value":"bandvaloper1ldtwjzsplhxzhrg3k5hhr8v0qterv05vpdxp9f"}]}]}],"gasWanted":"2000000","gasUsed":"566496"}
```
### Sending BAND token
The process of sending BAND token is similar to making a request, except we will use `MsgSend` as our message.
The `MsgSend` contains the following parameters
- **from_address** `<str>`: The sender address which is in string.
- **to_address** `<str>`: The receiver address which is in string.
- **amount** `<int>`: The amount of BAND in Coin that you want to send. In this case, we want to send 1 BAND or 1000000 UBAND
``` python
# from pyband.proto.cosmos.bank.v1beta1.tx_pb2 import MsgSend
msg = MsgSend(
from_address = sender,
to_address = "band1jrhuqrymzt4mnvgw8cvy3s9zhx3jj0dq30qpte",
amount = [Coin(amount="100", denom="uband")]
)
```
The final code should look like the code below.
``` python
import os
from pyband.client import Client
from pyband.transaction import Transaction
from pyband.wallet import PrivateKey
from pyband.proto.cosmos.base.v1beta1.coin_pb2 import Coin
from pyband.proto.cosmos.bank.v1beta1.tx_pb2 import MsgSend
from google.protobuf.json_format import MessageToJson
def main():
# Step 1
grpc_url = "rpc-laozi-testnet2.bandchain.org:9090"
c = Client(grpc_url)
# Step 2
MNEMONIC = os.getenv("MNEMONIC")
private_key = PrivateKey.from_mnemonic(MNEMONIC)
public_key = private_key.to_public_key()
sender_addr = public_key.to_address()
sender = sender_addr.to_acc_bech32()
# Step 3
send_msg = MsgSend(
from_address = sender,
to_address = "band1jrhuqrymzt4mnvgw8cvy3s9zhx3jj0dq30qpte",
amount = [Coin(amount="1000000", denom="uband")]
)
account = c.get_account(sender)
account_num = account.account_number
sequence = account.sequence
fee = [Coin(amount="0", denom="uband")]
chain_id = c.get_chain_id()
# Step 4
txn = (
Transaction()
.with_messages(send_msg)
.with_sequence(sequence)
.with_account_num(account_num)
.with_chain_id(chain_id)
.with_gas(2000000)
.with_fee(fee)
.with_memo("")
)
# Step 5
sign_doc = txn.get_sign_doc(public_key)
signature = private_key.sign(sign_doc.SerializeToString())
tx_raw_bytes = txn.get_tx_data(signature, public_key)
# Step 6
tx_block = c.send_tx_block_mode(tx_raw_bytes)
print(MessageToJson(tx_block))
if __name__ == "__main__":
main()
```
The result should look like this.
```
{"height":"603302","txhash":"815F488B3F05F2CBDD57C433DBEAF01FBFB06F378716A8ECDF5888095D6F7F7C","data":"0A060A0473656E64","rawLog":"[{\"events\":[{\"type\":\"message\",\"attributes\":[{\"key\":\"action\",\"value\":\"send\"},{\"key\":\"sender\",\"value\":\"band18p27yl962l8283ct7srr5l3g7ydazj07dqrwph\"},{\"key\":\"module\",\"value\":\"bank\"}]},{\"type\":\"transfer\",\"attributes\":[{\"key\":\"recipient\",\"value\":\"band1jrhuqrymzt4mnvgw8cvy3s9zhx3jj0dq30qpte\"},{\"key\":\"sender\",\"value\":\"band18p27yl962l8283ct7srr5l3g7ydazj07dqrwph\"},{\"key\":\"amount\",\"value\":\"1000000uband\"}]}]}]","logs":[{"events":[{"type":"message","attributes":[{"key":"action","value":"send"},{"key":"sender","value":"band18p27yl962l8283ct7srr5l3g7ydazj07dqrwph"},{"key":"module","value":"bank"}]},{"type":"transfer","attributes":[{"key":"recipient","value":"band1jrhuqrymzt4mnvgw8cvy3s9zhx3jj0dq30qpte"},{"key":"sender","value":"band18p27yl962l8283ct7srr5l3g7ydazj07dqrwph"},{"key":"amount","value":"1000000uband"}]}]}],"gasWanted":"2000000","gasUsed":"49029"}
```
### Getting Reference Data
Getting reference data can be done by the following steps.
**Step 1:** Import `pyband` and put `grpc_url` as a parameter. Then initialize the client instance. Every method in client module can now be used.
``` python
from pyband.client import Client
def main():
# Step 1
grpc_url = "rpc-laozi-testnet2.bandchain.org:9090"
c = Client(grpc_url)
if __name__ == "__main__":
main()
```
**Step 2** After importing `Client`, `get_reference_data` function can now be used to get the latest price.
The function contains the following paramters
- **pairs** `<List[str]>`: list of cryptocurrency pairs
- **min_count** `<int>`: integer of min count
- **ask_count** `<int>`: integer of ask count
``` python
from pyband.client import Client
def main():
# Step 1
grpc_url = "rpc-laozi-testnet2.bandchain.org:9090"
c = Client(grpc_url)
# Step 2
print(c.get_reference_data(["BTC/USD", "ETH/USD"], 3, 4))
if __name__ == "__main__":
main()
```
The result should look like this.
```
[ReferencePrice(pair='BTC/USD', rate=34614.1, updated_at=ReferencePriceUpdated(base=1625655764, quote=1625715134)), ReferencePrice(pair='ETH/USD', rate=2372.53, updated_at=ReferencePriceUpdated(base=1625655764, quote=1625715134))]
```