Skip to content

Commit

Permalink
Merge pull request #8 from Ankvik-Tech-Labs/docs/web3/examples
Browse files Browse the repository at this point in the history
docs: Add a web3.py example directly to README
  • Loading branch information
Aviksaikat authored Dec 27, 2024
2 parents 9ea379a + dff2627 commit a75717d
Show file tree
Hide file tree
Showing 6 changed files with 179 additions and 12 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,4 @@ _version.py
.env
.idea/
*.pem
*.tape
1 change: 1 addition & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ repos:
hooks:
- id: trailing-whitespace
- id: check-added-large-files
args: ['--maxkb=1024']
- id: check-merge-conflict
- id: check-shebang-scripts-are-executable
- id: check-docstring-first
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,7 @@ All notable changes to this project will be documented in this file.
- Updated changelog
- Github actions updated
- Changelog updated
- Changelog updated
- Version updated to 0.0.2

<!-- generated by git-cliff -->
183 changes: 173 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@

<div align="center" markdown>

| Feature | Value |
|---------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Technology | [![Python](https://img.shields.io/badge/Python-3776AB.svg?style=flat&logo=Python&logoColor=white)](https://www.python.org/) [![Hatch project](https://img.shields.io/badge/%F0%9F%A5%9A-Hatch-4051b5.svg)](https://github.com/pypa/hatch) [![GitHub Actions](https://img.shields.io/badge/GitHub%20Actions-2088FF.svg?style=flat&logo=GitHub-Actions&logoColor=white)](https://github.com/features/actions) [![Pytest](https://img.shields.io/badge/Pytest-0A9EDC.svg?style=flat&logo=Pytest&logoColor=white)](https://github.com/Ankvik-Tech-Labs/web3-google-hsmweb3-google-hsm/actions/workflows/tests.yml/badge.svg) |
| Type Checking | [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) [![Checked with mypy](http://www.mypy-lang.org/static/mypy_badge.svg)](http://mypy-lang.org/) |
| Feature | Value |
|---------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Technology | [![Python](https://img.shields.io/badge/Python-3776AB.svg?style=flat&logo=Python&logoColor=white)](https://www.python.org/) [![Hatch project](https://img.shields.io/badge/%F0%9F%A5%9A-Hatch-4051b5.svg)](https://github.com/pypa/hatch) [![GitHub Actions](https://img.shields.io/badge/GitHub%20Actions-2088FF.svg?style=flat&logo=GitHub-Actions&logoColor=white)](https://github.com/features/actions) [![Pytest](https://img.shields.io/badge/Pytest-0A9EDC.svg?style=flat&logo=Pytest&logoColor=white)](https://github.com/Ankvik-Tech-Labs/web3-google-hsmweb3-google-hsm/actions/workflows/tests.yml/badge.svg) |
| Type Checking | [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) [![Checked with mypy](http://www.mypy-lang.org/static/mypy_badge.svg)](http://mypy-lang.org/) |
| CI/CD | [![Release](https://github.com/Ankvik-Tech-Labs/web3-google-hsm/actions/workflows/build.yml/badge.svg)](https://github.com/Ankvik-Tech-Labs/web3-google-hsm/actions/workflows/build.yml) [![Tests](https://github.com/Ankvik-Tech-Labs/web3-google-hsm/actions/workflows/tests.yml/badge.svg)](https://github.com/Ankvik-Tech-Labs/web3-google-hsm/actions/workflows/tests.yml) [![Labeler](https://github.com/Ankvik-Tech-Labs/web3-google-hsm/actions/workflows/labeler.yml/badge.svg)](https://github.com/Ankvik-Tech-Labs/web3-google-hsm/actions/workflows/labeler.yml) [![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://github.com/pre-commit/pre-commit) [![codecov](https://codecov.io/gh/Ankvik-Tech-Labs/web3-google-hsm/graph/badge.svg?token=CK69S336BL)](https://codecov.io/gh/Ankvik-Tech-Labs/web3-google-hsm) |
| Docs | [![Docs](https://github.com/Ankvik-Tech-Labs/web3-google-hsm/actions/workflows/documentation.yml/badge.svg)](https://github.com/Ankvik-Tech-Labs/web3-google-hsm/actions/workflows/build.yml) |
| Package | [![PyPI - Version](https://img.shields.io/pypi/v/web3-google-hsm.svg)](https://pypi.org/project/web3-google-hsm/) [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/web3-google-hsm)](https://pypi.org/project/web3-google-hsm/) [![PyPI - License](https://img.shields.io/pypi/l/web3-google-hsm)](https://pypi.org/project/web3-google-hsm/) |
| Meta | [![GitHub license](https://img.shields.io/github/license/Ankvik-Tech-Labs/web3-google-hsm?&color=1573D5)](https://github.com/Ankvik-Tech-Labs/web3-google-hsm/blob/main/LICENSE) [![GitHub last commit](https://img.shields.io/github/last-commit/Ankvik-Tech-Labs/web3-google-hsm?style=flat&color=1573D5)](https://github.com/Ankvik-Tech-Labs/web3-google-hsmweb3-google-hsm/commits/main) [![GitHub commit activity](https://img.shields.io/github/commit-activity/m/Ankvik-Tech-Labs/web3-google-hsm?style=flat&color=1573D5)](https://github.com/Ankvik-Tech-Labs/web3-google-hsmweb3-google-hsm/graphs/commit-activity) [![GitHub top language](https://img.shields.io/github/languages/top/Ankvik-Tech-Labs/web3-google-hsm?style=flat&color=1573D5)](https://github.com/Ankvik-Tech-Labs/web3-google-hsmweb3-google-hsm) |
| Docs | [![Docs](https://github.com/Ankvik-Tech-Labs/web3-google-hsm/actions/workflows/documentation.yml/badge.svg)](https://github.com/Ankvik-Tech-Labs/web3-google-hsm/actions/workflows/build.yml) |
| Package | [![PyPI - Version](https://img.shields.io/pypi/v/web3-google-hsm.svg)](https://pypi.org/project/web3-google-hsm/) [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/web3-google-hsm)](https://pypi.org/project/web3-google-hsm/) [![PyPI - License](https://img.shields.io/pypi/l/web3-google-hsm)](https://pypi.org/project/web3-google-hsm/) |
| Meta | [![GitHub license](https://img.shields.io/github/license/Ankvik-Tech-Labs/web3-google-hsm?&color=1573D5)](https://github.com/Ankvik-Tech-Labs/web3-google-hsm/blob/main/LICENSE) [![GitHub last commit](https://img.shields.io/github/last-commit/Ankvik-Tech-Labs/web3-google-hsm?style=flat&color=1573D5)](https://github.com/Ankvik-Tech-Labs/web3-google-hsmweb3-google-hsm/commits/main) [![GitHub commit activity](https://img.shields.io/github/commit-activity/m/Ankvik-Tech-Labs/web3-google-hsm?style=flat&color=1573D5)](https://github.com/Ankvik-Tech-Labs/web3-google-hsmweb3-google-hsm/graphs/commit-activity) [![GitHub top language](https://img.shields.io/github/languages/top/Ankvik-Tech-Labs/web3-google-hsm?style=flat&color=1573D5)](https://github.com/Ankvik-Tech-Labs/web3-google-hsmweb3-google-hsm) |

</div>

Expand All @@ -34,9 +34,10 @@ A Python library for using `Google Cloud HSM` services to sign Ethereum transact
pip install web3-google-hsm
```

# Usage
![demo](media/demo.gif)

## Environment Setup

# Environment Setup

### Google Cloud HSM Key

Expand Down Expand Up @@ -140,12 +141,174 @@ except ValueError as e:
print(f"Configuration error: {e}")
```

# Usage Guide

This guide demonstrates how to use the `Google Cloud KMS` Ethereum signer library for message and transaction signing.

## Prerequisites

Before you begin, ensure you have:
1. Set up your environment variables (see [README.md](../index.md))
2. Python `3.10` or higher installed
3. Access to a `Web3` provider (local or remote) (Optional)

## Basic Setup

```python
from web3_google_hsm.accounts.gcp_kms_account import GCPKmsAccount

account = GCPKmsAccount()

# Get the Ethereum address derived from your GCP KMS key
print(f"GCP KMS Account address: {account.address}")
```

## Message Signing

### Simple Message Signing
```python
# Sign a message
message = "Hello Ethereum!"
signed_message = account.sign_message(message)

# Access signature components
print(f"R: {signed_message.r.hex()}")
print(f"S: {signed_message.s.hex()}")
print(f"V: {signed_message.v}")
print(f"Full signature: {signed_message.to_hex()}")
```

### Message Signature Verification
```python
from eth_account.messages import encode_defunct
from web3 import Web3
# Create message hash
message_hash = encode_defunct(text=message)

# Initialize Web3 and GCP KMS account
w3 = Web3(Web3.HTTPProvider("http://localhost:8545"))

# Verify the signature using web3.py
recovered_address = w3.eth.account.recover_message(
message_hash,
vrs=(signed_message.v, signed_message.r, signed_message.s)
)

# Check if signature is valid
is_valid = recovered_address.lower() == account.address.lower()
print(f"Signature valid: {is_valid}")
```

## Transaction Signing

### Creating a Transaction
```python
tx = {
"from": account.address,
"chain_id": w3.eth.chain_id,
"nonce": w3.eth.get_transaction_count(account.address),
"value": w3.to_wei(0.000001, "ether"),
"data": "0x00",
"to": "0xa5D3241A1591061F2a4bB69CA0215F66520E67cf",
"type": 0,
"gas_limit": 1000000,
"gas_price": 300000000000,
}

# Convert dict to Transaction object and sign
signed_tx = account.sign_transaction(Transaction.from_dict(tx))
```

### Sending a Transaction
```python
if signed_tx:
# Send the transaction
tx_hash = w3.eth.send_raw_transaction(signed_tx)

# Wait for transaction receipt
receipt = w3.eth.wait_for_transaction_receipt(tx_hash)

print(f"Transaction hash: {receipt['transactionHash'].hex()}")
print(f"From: {receipt['from']}")
print(f"To: {receipt['to']}")
print(f"Gas used: {receipt['gasUsed']}")
```

### Transaction Signature Verification
```python
# Verify the transaction signature
recovered_address = w3.eth.account.recover_transaction(signed_tx)
is_valid = recovered_address.lower() == account.address.lower()
print(f"Signature valid: {is_valid}")
```

## Working with Local Test Networks

### Funding Your Account (for testing with Anvil/Hardhat)
```python
# Use a test account (Anvil's default funded account)
funded_account = w3.eth.account.from_key(
"0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"
)

# Create funding transaction
fund_tx = {
"from": funded_account.address,
"to": account.address,
"value": w3.to_wei(0.1, "ether"),
"gas": 21000,
"gasPrice": w3.eth.gas_price,
"nonce": w3.eth.get_transaction_count(funded_account.address),
"chainId": w3.eth.chain_id,
}

# Send funding transaction
signed_fund_tx = w3.eth.account.sign_transaction(fund_tx, funded_account.key)
fund_tx_hash = w3.eth.send_raw_transaction(signed_fund_tx.raw_transaction)
fund_receipt = w3.eth.wait_for_transaction_receipt(fund_tx_hash)
```

## Using with Different Networks

### Local Network (Anvil/Hardhat)
```python
w3 = Web3(Web3.HTTPProvider("http://localhost:8545"))
```

### Mainnet (via Infura)
```python
w3 = Web3(Web3.HTTPProvider(f"https://mainnet.infura.io/v3/{INFURA_KEY}"))
```

### Testnet (sepolia)
```python
w3 = Web3(Web3.HTTPProvider(f"https://sepolia.infura.io/v3/{INFURA_KEY}"))
```

## Error Handling

```python
from web3_google_hsm.types.ethereum_types import Transaction

try:
signed_message = account.sign_message("Hello")
except Exception as e:
print(f"Signing error: {e}")

try:
signed_tx = account.sign_transaction(Transaction.from_dict(tx))
if not signed_tx:
print("Failed to sign transaction")
except Exception as e:
print(f"Transaction error: {e}")
```


---

For more information see the following links.

**Documentation**: <a href="https://Aviksaikat.github.io/web3-google-hsm/" target="_blank">https://Aviksaikat.github.io/web3-google-hsm/</a>
**Documentation**: <a href="https://ankvik-tech-labs.github.io/web3-google-hsm" target="_blank">https://ankvik-tech-labs.github.io/web3-google-hsm/</a>

**Source Code**: <a href="https://github.com/Ankvik-Tech-Labs/web3-google-hsm" target="_blank">https://github.com/Ankvik-Tech-Labs/web3-google-hsm</a>

Expand Down
4 changes: 2 additions & 2 deletions examples/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
fund_tx = {
"from": funded_account.address,
"to": account.address,
"value": w3.to_wei(0.1, "ether"),
"value": w3.to_wei(10, "ether"),
"gas": 21000,
"gasPrice": w3.eth.gas_price,
"nonce": w3.eth.get_transaction_count(funded_account.address),
Expand All @@ -57,7 +57,7 @@
signed_fund_tx = w3.eth.account.sign_transaction(fund_tx, funded_account.key)
fund_tx_hash = w3.eth.send_raw_transaction(signed_fund_tx.raw_transaction)
fund_receipt = w3.eth.wait_for_transaction_receipt(fund_tx_hash)
console.print(f"Funded account with 0.1 ETH. TX hash: {fund_receipt['transactionHash'].hex()}")
console.print(f"Funded account with 10 ETH. TX hash: {fund_receipt['transactionHash'].hex()}")

# Now create and sign a transaction from our GCP KMS account
tx = {
Expand Down
Binary file added media/demo.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit a75717d

Please sign in to comment.