Skip to content
Open
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ This changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.
- 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 `.github/workflows/bot-office-hours.yml` to automate the Weekly Office Hour Reminder.
Copy link

Copilot AI Nov 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trailing whitespace at the end of the line.

Suggested change
- Added `.github/workflows/bot-office-hours.yml` to automate the Weekly Office Hour Reminder.
- Added `.github/workflows/bot-office-hours.yml` to automate the Weekly Office Hour Reminder.

Copilot uses AI. Check for mistakes.
- feat: Implement account creation with EVM-style alias transaction example.
Copy link

Copilot AI Nov 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changelog entry format is inconsistent with other entries in the file. Most entries follow the pattern "Add example demonstrating..." or "Added..." without the "feat:" prefix. For consistency, consider changing to: "Add example demonstrating account creation with EVM-style alias transaction in examples/account/create_account_with_alias_transaction.py"

Suggested change
- feat: Implement account creation with EVM-style alias transaction example.
- Add example demonstrating account creation with EVM-style alias transaction in `examples/account/create_account_with_alias_transaction.py`

Copilot uses AI. Check for mistakes.
- Added validation logic in `.github/workflows/pr-checks.yml` to detect when no new chnagelog entries are added under [Unreleased]

### Changed
Expand Down
115 changes: 115 additions & 0 deletions examples/account/account_create_transaction_evm_alias.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# uv run examples/account/account_create_transaction_evm_alias.py
# python examples/account/account_create_transaction_evm_alias.py
"""
Example: Create an account using an EVM-style alias (evm_address).
Copy link

Copilot AI Nov 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docstring is minimal compared to other examples in this directory (e.g., account_create_transaction.py). Consider adding a more comprehensive module-level docstring that includes:

  • A detailed description of what the example demonstrates
  • The specific features being showcased (ECDSA keys, EVM alias, etc.)
  • Usage instructions (how to run with python/uv)
  • Required environment variables
  • Expected outcomes

This would make the example more accessible and educational for users.

Suggested change
Example: Create an account using an EVM-style alias (evm_address).
Example: Create a Hedera account using an EVM-style alias (evm_address).
This example demonstrates how to:
- Generate a new ECDSA key pair.
- Derive an EVM-compatible address (alias) from the public key.
- Create a new Hedera account using the EVM address as an alias.
- Query and display the account information, including the contract account ID (alias).
Features showcased:
- ECDSA key generation
- EVM aliasing (evm_address)
- Account creation with alias
- Account info query
Usage:
uv run examples/account/create_account_with_alias_transaction.py
python examples/account/create_account_with_alias_transaction.py
Required environment variables (set in a .env file or your environment):
- OPERATOR_ID: The account ID of the operator (payer) account.
- OPERATOR_KEY: The private key of the operator account.
- NETWORK: (Optional) The Hedera network to use (default: testnet).
- KEY_TYPE: (Optional) The key type to use for the new account (default: ecdsa).
Expected outcome:
- A new Hedera account is created with an EVM-style alias.
- The script outputs the new account ID, EVM address, and detailed account information.
- The contract account ID (alias) is displayed if available.

Copilot uses AI. Check for mistakes.
"""

import os
import sys
import json
from dotenv import load_dotenv

from hiero_sdk_python import (
Client,
PrivateKey,
AccountCreateTransaction,
AccountInfoQuery,
Network,
AccountId,
Hbar,
)

load_dotenv()
network_name = os.getenv('NETWORK', 'testnet').lower()

def setup_client():
"""Setup Client """
Copy link

Copilot AI Nov 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docstring "Setup Client " is incomplete and lacks detail. Following the pattern in account_create_transaction.py, consider expanding this to document:

  • What the function does (connects to network, configures operator)
  • Return type and what's returned
  • Exceptions that may be raised
  • Required environment variables

Also note the trailing space in "Client " which should be removed.

Suggested change
"""Setup Client """
"""
Set up and return a Hedera Client configured for the specified network and operator.
This function connects to the Hedera network specified by the NETWORK environment variable,
and configures the client with the operator account and private key from the environment.
Returns:
Client: A configured Hedera Client instance.
Raises:
SystemExit: If required environment variables are missing or invalid.
Required Environment Variables:
- OPERATOR_ID: The account ID of the operator (payer) account.
- OPERATOR_KEY: The private key of the operator account.
- NETWORK: The Hedera network to connect to (e.g., 'testnet', 'mainnet', 'previewnet'). Defaults to 'testnet'.
- KEY_TYPE: The type of key to use (e.g., 'ecdsa'). Defaults to 'ecdsa'.
"""

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI Nov 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trailing whitespace after "Client".

Suggested change
"""Setup Client """
"""Setup Client"""

Copilot uses AI. Check for mistakes.
network = Network(network_name)
print(f"Connecting to Hedera {network_name} network!")
client = Client(network)

# Get the operator account from the .env file
try:
operator_id = AccountId.from_string(os.getenv('OPERATOR_ID', ''))
operator_key = PrivateKey.from_string(os.getenv('OPERATOR_KEY', ''))
# Set the operator (payer) account for the client
client.set_operator(operator_id, operator_key)
print(f"Client set up with operator id {client.operator_account_id}")
return client
except Exception:
print("Error: Please check OPERATOR_ID and OPERATOR_KEY in your .env file.")
sys.exit(1)

def info_to_dict(info):
"""Convert AccountInfo to dictionary for easy printing."""
out = {}
for name in dir(info):
if name.startswith("_"):
continue
try:
val = getattr(info, name)
except Exception as error:
out[name] = f"Error retrieving value: {error}"
continue
if callable(val):
continue
out[name] = str(val)
return out

def create_account_with_alias(client):
"""Create an account with an alias transaction."""
try:
print("\nSTEP 1: Generating a new ECDSA key pair for the account alias...")
private_key = PrivateKey.generate('ecdsa')
public_key = private_key.public_key()
evm_address = public_key.to_evm_address()
if evm_address is None:
print("❌ Error: Failed to generate EVM address from public key.")
sys.exit(1)
print(f"✅ Generated new ECDSA key pair. EVM Address (alias): {evm_address}")
# Create the account with the alias
print("\nSTEP 2: Creating the account with the EVM address alias...")
transaction = (
AccountCreateTransaction()
.set_key(public_key)
.set_initial_balance(Hbar(5))
.set_alias(evm_address)
)

# Sign the transaction with both the new key and the operator key
transaction = transaction.freeze_with(client) \
.sign(private_key) \
.sign(client.operator_private_key)

# Execute the transaction
response = transaction.execute(client)
new_account_id = response.account_id
print(f"✅ Account created with ID: {new_account_id}\n")
# Fetch and display account info
account_info = AccountInfoQuery().set_account_id(new_account_id).execute(client)
# Print the account info
out = info_to_dict(account_info)
print("🧾 Account Info:")
print(json.dumps(out, indent=2) + "\n")
if account_info.contract_account_id is not None:
print(f"✅ Contract Account ID (alias): {account_info.contract_account_id}")
else:
print("❌ Error: Contract Account ID (alias) does not exist.")

except Exception as error:
print(f"❌ Error: {error}")
sys.exit(1)

def main():
"""Main function to create an account with an alias transaction.
1- Setup client
2- Generate ECDSA key pair and EVM address alias
3- Create account with alias
4- Print account info
"""
client = setup_client()
create_account_with_alias(client)


if __name__ == "__main__":
main()