Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ This changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.

### Added

- Added docs/sdk_developers/training/setup: a training to set up as a developer to the python sdk
- Add example demonstrating usage of `CustomFeeLimit` in `examples/transaction/custom_fee_limit.py`
- Added `.github/workflows/merge-conflict-bot.yml` to automatically detect and notify users of merge conflicts in Pull Requests.
- Added validation logic in `.github/workflows/pr-checks.yml` to detect when no new chnagelog entries are added under [Unreleased]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
## What is the Hiero Python SDK?

The Hiero Python SDK enables developers to use Python to interact with the Hedera Blockchain/DLT Network.

For example, the Hiero Python SDK lets you:
- Create a token on the Hedera network
- Transfer Hbars between accounts
- Mint NFTs
- Create smart contracts

All using python code.

For example:
```python
create_tx = (
TokenCreateTransaction()
.set_token_name("Example Token")
.set_token_symbol("EXT")
.set_treasury_account_id(operator_id)
.freeze_with(client)
.sign(operator_key)
.execute(client)
)

token_id = create_tx.token_id
print(f"🎉 Created a new token on the Hedera network with ID: {token_id}")
```

Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
## Quick Set-up

### Fork the Hiero Python SDK
Create your GitHub fork, then clone your fork locally and connect it to the upstream repo to make it easy to sync in the future.

```bash
git clone https://github.com/YOUR_GITHUB_USERNAME/hiero-sdk-python.git
cd hiero-sdk-python
# Add upstream for future syncing
git remote add upstream https://github.com/hiero-ledger/hiero-sdk-python.git
```

### Install Packages
This installs the package manager uv:
```bash
curl -LsSf https://astral.sh/uv/install.sh | sh
exec $SHELL
```

Now install dependencies as per pyproject.toml:
```bash
uv sync
```

### Generate Protobufs
The SDK uses protobuf definitions to generate gRPC and model classes.

Run:
```bash
uv run python generate_proto.py
```

27 changes: 27 additions & 0 deletions docs/sdk_developers/training/setup/03_setting_up_env.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
## Quick Start Env

### 1. Create Testnet Account

Create a testnet Hedera Portal account [here](https://portal.hedera.com/dashboard).

### 2. Create .env
Create a file named `.env` in your project root.

Add, ignoring the < > and without any quotation marks:

```bash
OPERATOR_ID=<YOUR_OPERATOR_ID> #your account id
OPERATOR_KEY=<YOUR_PRIVATE_KEY> #your testnet private key (can be ECDSA, ED25519 or DER)
NETWORK=testnet
```

For example:
```bash
OPERATOR_ID=0.0.1000000
OPERATOR_KEY=123456789
NETWORK=testnet
```

We have added `.env` to `.gitignore` to help ensure its never committed.


27 changes: 27 additions & 0 deletions docs/sdk_developers/training/setup/04_using_env_variables.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
## Loading Credentials Into Scripts

Your credentials stored at .env are required to run transactions on Hedera testnet.

- dotenv has load_dotenv() to load credentails
- os has getenv() to read the credentials

We use both, for example:

```python
# Import dotenv and os
from dotenv import load_dotenv
from os import getenv

# Load variables from .env into environment
load_dotenv()

# Read the variables
operator_id_string = getenv('OPERATOR_ID')
operator_key_string = getenv('OPERATOR_KEY')

# Printing confirming loading and reading
print(f"Congratulations! We loaded your operator ID: {operator_id_string}.")
print("Your operator key was loaded successfully (not printed for security).")

```

55 changes: 55 additions & 0 deletions docs/sdk_developers/training/setup/05_network_client_setup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
## Setup Network and Client

All transactions and queries on the Hedera network require a network and client set-up.

To do this you'll need to import the relevant functionality, variables from .env and attach them to the Network and Client classes as appropriate.

### Worked Example
```python
import sys
from dotenv import load_dotenv
from os import getenv

from hiero_sdk_python.account.account_id import AccountId
from hiero_sdk_python.crypto.private_key import PrivateKey
from hiero_sdk_python.client.client import Client
from hiero_sdk_python.client.network import Network
from hiero_sdk_python.tokens.token_create_transaction import TokenCreateTransaction
from hiero_sdk_python.client import client
from hiero_sdk_python.response_code import ResponseCode

# 1. Setup Client
load_dotenv()
operator_id = AccountId.from_string(getenv('OPERATOR_ID',''))
operator_key = PrivateKey.from_string(getenv('OPERATOR_KEY',''))

network = Network(getenv('NETWORK',''))
client = Client(network)
client.set_operator(operator_id, operator_key)

# 2. Build the transaction
create_tx = (
TokenCreateTransaction()
.set_token_name("Example Token")
.set_token_symbol("EXT")
.set_treasury_account_id(operator_id)
.set_initial_supply(100000)
.freeze_with(client)
.sign(operator_key)
)

# 3. Execute and get receipt
receipt = create_tx.execute(client)

# 4. Validate Success
if receipt.status != ResponseCode.SUCCESS:
print(f"Token creation on Hedera failed: {ResponseCode(receipt.status).name}")
sys.exit(1)

# 5. Extract the Token ID
token_id = receipt.token_id
print(f"🎉 Created new token on the Hedera network with ID: {token_id}")
```

### Extra Support
Read about Network and Client in more detail [here](docs/sdk_developers/training/network_and_client.md)
76 changes: 76 additions & 0 deletions docs/sdk_developers/training/setup/06_importing_hiero_files.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
## Importing Functionality To Use In Scripts

Import all modules, classes and types required for your transaction to work by specifying their exact path after src/.

### Example: Importing TokenCreateTransactionClass
TokenCreateTransaction class is located inside src/hiero_sdk_python/tokens/token_create_transaction.py:

Therefore:
```python
from hiero_sdk_python.tokens.token_create_transaction import TokenCreateTransaction
```

### Example: Importing token_create_transaction.py
token_create_transaction.py is located at src/hiero_sdk_python/tokens.py:

Therefore:
```python
from hiero_sdk_python.tokens import token_create_transaction
```

### Advanced Example
You'll need to import everything you require.

In this more advanced example, we are using imports to load env, to set up the client and network, and to form the Token Create Transaction and check the response:

```python
import sys
from dotenv import load_dotenv
from os import getenv

from hiero_sdk_python.account.account_id import AccountId
from hiero_sdk_python.crypto.private_key import PrivateKey
from hiero_sdk_python.client.client import Client
from hiero_sdk_python.client.network import Network
from hiero_sdk_python.tokens.token_create_transaction import TokenCreateTransaction
from hiero_sdk_python.response_code import ResponseCode

# 1. Setup Client
load_dotenv()
operator_id = AccountId.from_string(getenv('OPERATOR_ID',''))
operator_key = PrivateKey.from_string(getenv('OPERATOR_KEY',''))

network = Network(getenv('NETWORK',''))
client = Client(network)
client.set_operator(operator_id, operator_key)

# 2. Build the transaction
create_tx = (
TokenCreateTransaction()
.set_token_name("Example Token")
.set_token_symbol("EXT")
.set_treasury_account_id(operator_id)
.set_initial_supply(100000)
.freeze_with(client)
.sign(operator_key)
)

# 3. Execute and get receipt
receipt = create_tx.execute(client)

# 4. Validate Success
if receipt.status != ResponseCode.SUCCESS:
print(f"Token creation on Hedera failed: {ResponseCode(receipt.status).name}")
sys.exit(1)

# 5. Extract the Token ID
token_id = receipt.token_id
print(f"🎉 Created new token on the Hedera network with ID: {token_id}")
```

## Extra Support
It takes time to be familiar with where everything is located to import correctly.

- For reference, look at the [examples](examples/)
- For an explanation of the project structure read [project_structure.md](docs/sdk_developers/project_structure.md).
- Set up [Pylance](docs/sdk_developers/pylance.md) to help you spot errors in your import locations
102 changes: 102 additions & 0 deletions docs/sdk_developers/training/setup/07_lab_set_up.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
## Lab: Setup

In this lab, you'll set up a Network and Client instance and run an account balance query on the Hedera network.

## Step 1: Create a file at /examples/lab1.py
Create a lab1 practice file and add a main function:
```python
def main():
# Placeholder to call functions

if __name__ == "__main__":
main()
```
You'll be running this by: "uv run /examples/practice.py"

## Step 2: Create a function: set_up_network_and_client
In this function be sure to:
- Import required packages
- Load OPERATOR_ID as operator_id_string, OPERATOR_KEY as operator_key_string
- Connect to Hedera testnet
- Connect your credentials to the Client

Note: Check it works by running the file at "uv run /examples/practice.py"
```python
def set_up_network_and_client():
# Placeholder to set up network and client

def main():
# Call the function and return any needed variables
set_up_network_and_client()

if __name__ == "__main__":
main()
```

## Step 3: Create query_account_balance
- Pass in the client and operator_key
- Perform an account balance query
- Print the hbar balance
- Print the token balance
- Call this from main()

Syntax:
```python
balance = CryptoGetAccountBalanceQuery(operator_id).execute(client)
print(f" Hbar balance is {balance.hbars}")
print(f" Token balance is {balance.token_balances}")
```

Your main will now look more like this:
```python
def main():
client, operator_id = set_up_network_and_client()
query_account_balance(client, operator_id)

if __name__ == "__main__":
main()
```

Check it all works by running it "uv run /examples/practice.py"


#### Solution: WARNING!

```python
from dotenv import load_dotenv
from os import getenv
from hiero_sdk_python.account.account_id import AccountId
from hiero_sdk_python.crypto.private_key import PrivateKey
from hiero_sdk_python.client.client import Client
from hiero_sdk_python.client.network import Network
from hiero_sdk_python.query.account_balance_query import CryptoGetAccountBalanceQuery

def set_up_network_and_client():
load_dotenv()

network_name = getenv('NETWORK','')
network = Network(network_name)
client = Client(network)

operator_id_string = getenv('OPERATOR_ID','')
operator_key_string = getenv('OPERATOR_KEY','')

operator_id = AccountId.from_string(operator_id_string)
operator_key = PrivateKey.from_string(operator_key_string)

client.set_operator(operator_id, operator_key)
print(f"Connected to Hedera {network_name} as operator {client.operator_account_id}")
return client, operator_id

def query_account_balance(client, operator_id):
balance = CryptoGetAccountBalanceQuery(operator_id).execute(client)
print(f" Hbar balance is {balance.hbars}")
print(f" Token balance is {balance.token_balances}")

def main():
client, operator_id = set_up_network_and_client()
query_account_balance(client, operator_id)

if __name__ == "__main__":
main()
```