Installation varies between operating systems.
See our documentation on complete instructions
A Client is a facade for interacting with Starknet. FullNodeClient is a client which interacts with a Starknet full nodes like Pathfinder, Papyrus or Juno. It supports read and write operations, like querying the blockchain state or adding new transactions.
fromstarknet_py.net.full_node_clientimportFullNodeClientnode_url="https://your.node.url"client=FullNodeClient(node_url=node_url)
call_result=awaitclient.get_block(block_number=1)The default interface is asynchronous. Although it is the recommended way of using starknet.py, you can also use a synchronous version. It might be helpful to play with Starknet directly in python interpreter.
node_url="https://your.node.url"client=FullNodeClient(node_url=node_url)
call_result=client.get_block_sync(block_number=1)You can check out all of the FullNodeClientโs methods here: FullNodeClient.
Account is the default implementation of BaseAccount interface. It supports an account contract which proxies the calls to other contracts on Starknet.
Account can be created in two ways:
- By constructor (It is required to provide an
addressand eitherkey_pairorsigner). - By static method
Account.deploy_account_v3
Additionally, you can use the sncast tool to create an account, which will automatically be saved to a file. There are some examples how to do it:
fromstarknet_py.net.account.accountimportAccountfromstarknet_py.net.full_node_clientimportFullNodeClientfromstarknet_py.net.models.chainsimportStarknetChainIdfromstarknet_py.net.signer.key_pairimportKeyPairfromstarknet_py.net.signer.stark_curve_signerimportStarkCurveSigner# Creates an instance of account which is already deployed# Account using transaction version=1 (has __validate__ function)client=FullNodeClient(node_url="https://your.node.url")
account=Account(
client=client,
address="0x4321",
key_pair=KeyPair(private_key=654, public_key=321),
chain=StarknetChainId.SEPOLIA,
)
# There is another way of creating key_pairkey_pair=KeyPair.from_private_key(key=123)
# orkey_pair=KeyPair.from_private_key(key="0x123")
# Instead of providing key_pair it is possible to specify a signersigner=StarkCurveSigner("0x1234", key_pair, StarknetChainId.SEPOLIA)
account=Account(
client=client, address="0x1234", signer=signer, chain=StarknetChainId.SEPOLIA
)Example usage:
fromstarknet_py.contractimportContractfromstarknet_py.net.client_modelsimportResourceBounds, ResourceBoundsMappingresource_bounds=ResourceBoundsMapping(
l1_gas=ResourceBounds(max_amount=int(1e5), max_price_per_unit=int(1e13)),
l2_gas=ResourceBounds(max_amount=int(1e5), max_price_per_unit=int(1e13)),
l1_data_gas=ResourceBounds(max_amount=int(1e5), max_price_per_unit=int(1e13)),
)
# Declare and deploy an example contract which implements a simple k-v store.# Contract.declare_v3 takes string containing a compiled contract (sierra) and# a class hash (casm_class_hash) or string containing a compiled contract (casm)declare_result=awaitContract.declare_v3(
account,
compiled_contract=compiled_contract,
compiled_class_hash=class_hash,
resource_bounds=resource_bounds,
)
awaitdeclare_result.wait_for_acceptance()
deploy_result=awaitdeclare_result.deploy_v3(
resource_bounds=resource_bounds,
)
# Wait until deployment transaction is acceptedawaitdeploy_result.wait_for_acceptance()
# Get deployed contractmap_contract=deploy_result.deployed_contractk, v=13, 4324# Adds a transaction to mutate the state of k-v store. The call goes through account proxy, because we've used# Account to create the contract objectawait (
awaitmap_contract.functions["put"].invoke_v3(
k,
v,
resource_bounds=resource_bounds,
)
).wait_for_acceptance()
# Retrieves the value, which is equal to 4324 in this case
(resp,) =awaitmap_contract.functions["get"].call(k)
# There is a possibility of invoking the multicall# Creates a list of prepared function callscalls= [
map_contract.functions["put"].prepare_invoke_v3(key=10, value=20),
map_contract.functions["put"].prepare_invoke_v3(key=30, value=40),
]
# Executes only one transaction with prepared callstransaction_response=awaitaccount.execute_v3(
calls=calls,
resource_bounds=resource_bounds,
)
awaitaccount.client.wait_for_tx(transaction_response.transaction_hash)Contract makes interacting with contracts deployed on Starknet much easier:
fromstarknet_py.contractimportContractfromstarknet_py.net.client_modelsimportResourceBounds, ResourceBoundsMappingcontract_address= (
"0x01336fa7c870a7403aced14dda865b75f29113230ed84e3a661f7af70fe83e7b"
)
key=1234# Create contract from contract's address - Contract will download contract's ABI to know its interface.contract=awaitContract.from_address(address=contract_address, provider=account)
# If the ABI is known, create the contract directly (this is the preferred way).contract=Contract(
address=contract_address,
abi=abi,
provider=account,
cairo_version=1,
)
# All exposed functions are available at contract.functions.# Here we invoke a function, creating a new transaction.resource_bounds=ResourceBoundsMapping(
l1_gas=ResourceBounds(max_amount=int(1e5), max_price_per_unit=int(1e13)),
l2_gas=ResourceBounds(max_amount=int(1e5), max_price_per_unit=int(1e13)),
l1_data_gas=ResourceBounds(max_amount=int(1e5), max_price_per_unit=int(1e13)),
)
invocation=awaitcontract.functions["put"].invoke_v3(
key,
7,
resource_bounds=resource_bounds,
)
# Invocation returns InvokeResult object. It exposes a helper for waiting until transaction is accepted.awaitinvocation.wait_for_acceptance()
# Calling contract's function doesn't create a new transaction, you get the function's result.
(saved,) =awaitcontract.functions["get"].call(key)
# saved = 7 nowTo check if invoke succeeded use wait_for_acceptance on InvokeResult and get its status.
Although asynchronous API is recommended, you can also use Contractโs synchronous API:
fromstarknet_py.contractimportContractfromstarknet_py.net.client_modelsimportResourceBounds, ResourceBoundsMappingcontract_address= (
"0x01336fa7c870a7403aced14dda865b75f29113230ed84e3a661f7af70fe83e7b"
)
key=1234contract=Contract.from_address_sync(address=contract_address, provider=account)
resource_bounds=ResourceBoundsMapping(
l1_gas=ResourceBounds(max_amount=int(1e5), max_price_per_unit=int(1e13)),
l2_gas=ResourceBounds(max_amount=int(1e5), max_price_per_unit=int(1e13)),
l1_data_gas=ResourceBounds(max_amount=int(1e5), max_price_per_unit=int(1e13)),
)
invocation=contract.functions["put"].invoke_v3_sync(key, 7, resource_bounds=resource_bounds)
invocation.wait_for_acceptance_sync()
(saved,) =contract.functions["get"].call_sync(key) # 7Contract automatically serializes values to Cairo calldata. This includes adding array lengths automatically. See more info in Serialization.
Quickstart in docs - click here.
