Skip to main content

Web3.py extension for Tempo blockchain - adds support for AA transactions and Tempo-specific features

Project description



tempo combomark



pytempo

Web3.py extension for Tempo.

Installation

pip install pytempo

Or with uv:

uv add pytempo

Quick Start

Typed Contract Helpers (v0.4.0+)

Use the built-in typed helpers for Tempo precompiles — no ABI knowledge needed:

from pytempo import TempoTransaction
from pytempo.contracts import TIP20, StablecoinDEX, ALPHA_USD, BETA_USD
from web3 import Web3

w3 = Web3(Web3.HTTPProvider("https://rpc.testnet.tempo.xyz"))

# Create a strongly-typed immutable transaction
# No patching needed - we handle encoding ourselves
tx = TempoTransaction.create(
    chain_id=42429,
    gas_limit=100_000,
    max_fee_per_gas=2_000_000_000,
    max_priority_fee_per_gas=1_000_000_000,
    nonce=0,
    calls=(
        TIP20(ALPHA_USD).approve(spender=StablecoinDEX.ADDRESS, amount=10**18),
        StablecoinDEX.place(token=BETA_USD, amount=100_000_000, is_bid=True, tick=10),
    ),
)
signed_tx = tx.sign("0xYourPrivateKey...")

# Send using web3.py
tx_hash = w3.eth.send_raw_transaction(signed_tx.encode())

Manual Calls (v0.2.1+)

For arbitrary contract calls or simple transfers, use Call.create() directly:

from pytempo import TempoTransaction, Call
from web3 import Web3

w3 = Web3(Web3.HTTPProvider("https://rpc.testnet.tempo.xyz"))

tx = TempoTransaction.create(
    chain_id=42429,
    gas_limit=100_000,
    max_fee_per_gas=2_000_000_000,
    max_priority_fee_per_gas=1_000_000_000,
    nonce=0,
    calls=(Call.create(to="0xRecipient...", value=1000),),
)
signed_tx = tx.sign("0xYourPrivateKey...")
tx_hash = w3.eth.send_raw_transaction(signed_tx.encode())

Custom Fee Tokens (v0.2.1+)

from pytempo.contracts import BETA_USD

tx = TempoTransaction.create(
    chain_id=42429,
    gas_limit=100_000,
    max_fee_per_gas=2_000_000_000,
    fee_token=BETA_USD,
    calls=(Call.create(to="0xRecipient...", value=1000),),
)

Gas Sponsorship (v0.2.1+)

from pytempo import TempoTransaction, Call

# User creates and signs a sponsored transaction
tx = TempoTransaction.create(
    chain_id=42429,
    gas_limit=100_000,
    max_fee_per_gas=2_000_000_000,
    awaiting_fee_payer=True,
    calls=(Call.create(to="0xRecipient...", value=1000),),
)
signed_tx = tx.sign("0xUserPrivateKey...")

# Fee payer signs (pays gas)
final_tx = signed_tx.sign("0xFeePayerPrivateKey...", for_fee_payer=True)

w3.eth.send_raw_transaction(final_tx.encode())

Batch Multiple Calls (v0.2.1+)

from pytempo import TempoTransaction, Call

tx = TempoTransaction.create(
    chain_id=42429,
    gas_limit=200_000,
    max_fee_per_gas=2_000_000_000,
    calls=(
        Call.create(to="0xAddress1...", value=100000),
        Call.create(to="0xAddress2...", value=200000, data="0xabcdef"),
    ),
)
signed_tx = tx.sign("0xPrivateKey...")

Parallel Nonces (v0.2.1+)

from pytempo import TempoTransaction, Call

# Use different nonce keys for parallel execution
tx1 = TempoTransaction.create(
    chain_id=42429,
    gas_limit=100_000,
    nonce=0,
    nonce_key=1,  # First parallel key
    calls=(Call.create(to="0xRecipient..."),),
)

tx2 = TempoTransaction.create(
    chain_id=42429,
    gas_limit=100_000,
    nonce=0,
    nonce_key=2,  # Second parallel key
    calls=(Call.create(to="0xRecipient..."),),
)

# Both can be executed in parallel

Contract Creation (v0.2.1+)

from pytempo import TempoTransaction, Call

tx = TempoTransaction.create(
    chain_id=42429,
    gas_limit=500_000,
    calls=(Call.create(to=b"", data="0x6080604052..."),),  # Empty 'to' for creation
)
signed_tx = tx.sign("0xPrivateKey...")

Parsing from Dicts (v0.2.1+)

from pytempo import TempoTransaction

# Supports both camelCase and snake_case keys
tx = TempoTransaction.from_dict({
    "chainId": 42429,
    "gas": 100_000,
    "maxFeePerGas": 2_000_000_000,
    "to": "0xRecipient...",
    "value": 1000,
})

Type Coercion Helpers (v0.2.1+)

from pytempo import as_address, as_hash32, as_bytes, as_optional_address

# Validate and convert addresses
addr = as_address("0xF0109fC8DF283027b6285cc889F5aA624EaC1F55")  # -> bytes (20)
addr = as_address(b"\x00" * 20)  # Also accepts bytes

# Optional addresses (treats empty as None)
addr = as_optional_address("0x")  # -> None
addr = as_optional_address(None)  # -> None

# Validate 32-byte hashes
h = as_hash32("0x" + "ab" * 32)  # -> bytes (32)

# Convert hex strings to bytes
data = as_bytes("0xabcdef")  # -> b'\xab\xcd\xef'

API Reference

TempoTransaction

Immutable, strongly-typed transaction (frozen attrs model).

Factory Methods:

  • TempoTransaction.create(**kwargs) - Create with type coercion
  • TempoTransaction.from_dict(d) - Parse from camelCase/snake_case dict

Create Parameters:

  • chain_id (int) - Chain ID (default: 1)
  • gas_limit (int) - Gas limit (default: 21_000)
  • max_fee_per_gas (int) - Max fee per gas in wei
  • max_priority_fee_per_gas (int) - Max priority fee per gas in wei
  • nonce (int) - Transaction nonce
  • nonce_key (int) - Nonce key for parallel execution
  • valid_before (int, optional) - Expiration timestamp
  • valid_after (int, optional) - Activation timestamp
  • fee_token (str/bytes, optional) - Fee token address
  • awaiting_fee_payer (bool) - Mark for fee payer signature
  • calls (tuple[Call, ...]) - Tuple of Call objects
  • access_list (tuple[AccessListItem, ...]) - EIP-2930 access list

Methods:

  • sign(private_key, for_fee_payer=False) - Sign transaction (returns new instance)
  • sign_access_key(access_key_private_key, root_account) - Sign with access key (returns new instance)
  • encode() - Encode to bytes for transmission
  • hash() - Get transaction hash
  • get_signing_hash(for_fee_payer=False) - Get hash to sign
  • vrs() - Get v, r, s values
  • validate() - Validate transaction fields

Call

Single call in a batch transaction.

  • Call.create(to, value=0, data=b"") - Create with type coercion

AccessListItem

EIP-2930 access list entry.

  • AccessListItem.create(address, storage_keys=()) - Create with type coercion

Contract Helpers

Typed call builders for Tempo precompiles and tokens:

  • TIP20 — TIP-20 token operations (transfer, approve, mint, burn, permit)
  • StablecoinDEX — Stablecoin DEX operations (place, cancel, swap, withdraw)
  • AccountKeychain — Access key management (authorize, revoke, spending limits, queries)
  • FeeAMM — Fee AMM liquidity operations (mint, burn, rebalance_swap)
  • FeeManager — Fee manager operations (set fee token, distribute fees); inherits FeeAMM
  • Nonce — Nonce precompile queries (get_nonce)

Development

make install  # Install dependencies
make test     # Run tests
make lint     # Lint
make format   # Format code
make check    # Run all checks (lint + format-check + test)

Examples

See the examples/ directory:

  • simple_send.py - Simple value transfer
  • basic_transaction.py - Transaction with fee token
  • fee_payer_sponsored.py - Gas sponsorship and call batching

Contributing

Our contributor guidelines can be found in CONTRIBUTING.md.

Security

See SECURITY.md. Note: Tempo is still undergoing audit and does not have an active bug bounty. Submissions will not be eligible for a bounty until audits have concluded.

License

Licensed under either of Apache License, Version 2.0 or MIT License at your option.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in these crates by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pytempo-0.5.1.tar.gz (267.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pytempo-0.5.1-py3-none-any.whl (38.4 kB view details)

Uploaded Python 3

File details

Details for the file pytempo-0.5.1.tar.gz.

File metadata

  • Download URL: pytempo-0.5.1.tar.gz
  • Upload date:
  • Size: 267.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for pytempo-0.5.1.tar.gz
Algorithm Hash digest
SHA256 3f70c0bb8b3111b7eb56a334e22df0eeb715b8f35d77fced11358e8d487a6bad
MD5 a2b7652f9679ffe29f5f5db698daa35e
BLAKE2b-256 f35b2a31105f61a75413a8a61274443d610a7813142c1638956c76d963228896

See more details on using hashes here.

File details

Details for the file pytempo-0.5.1-py3-none-any.whl.

File metadata

  • Download URL: pytempo-0.5.1-py3-none-any.whl
  • Upload date:
  • Size: 38.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for pytempo-0.5.1-py3-none-any.whl
Algorithm Hash digest
SHA256 3e912ad4e81455e54523d93dd27cf06921c624b56ec622a4d16e7726640cb04c
MD5 6a7ba2dae14c6dc2bcf8a7818a89510b
BLAKE2b-256 eb5185d4f411c8768b3308b2ef40365f98b7d64ef33655b6bc67f612cdce9416

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page