declare!
declare! is a compile-time checked variant of declare. It accepts a Cairo path instead
of a string literal and adds a compile-time check that ContractState exists under the given path.
The macro expands to a regular declare(...) call, so contract artifact resolution still happens at runtime.
📝 Note This compile-time check only verifies that the contract path exists as a Cairo type path. It does not validate the contract contents, ABI, entrypoints, or that the resolved artifact has the shape expected by the test.
Accepted paths are:
- full module tree paths (e.g.
my_package::module::MyContract) - partial module tree paths (e.g.
module::MyContract) - contract names (e.g.
MyContract)
Contract names require the contract to be in scope, either by being defined in the same module or imported.
use declare_examples::hello_starknet::HelloStarknet;
use snforge_std::DeclareResultTrait;
#[test]
fn test_declare() {
let contract = declare!(HelloStarknet).unwrap().contract_class();
// ...
}
Partial module tree paths require their first segment to be in scope:
use declare_examples::hello_starknet;
use snforge_std::DeclareResultTrait;
#[test]
fn test_declare_partial_path() {
let contract = declare!(hello_starknet::HelloStarknet).unwrap().contract_class();
// ...
}
Limitations
declare! is type-safe only from the contract path existence perspective. IIt should not be treated as a compile-time guarantee that the contract is valid, or that compilation/declaration will succeed.
Currently, declare! does not resolve Cairo aliases. The path passed to the macro is also passed to the runtime
contract resolver. This means that such code will not work:
use my_package::module::MyContract as Alias;
use snforge_std::{ContractClassTrait, DeclareResultTrait};
#[test]
fn declare_by_alias() {
let contract = declare!(Alias).unwrap().contract_class();
}
For contract names, the compile-time check uses the name visible in scope, but
runtime artifact resolution still uses the name string. If multiple contracts
share the same name, declare!(MyContract) can still fail due to ambiguity. Use a
module path in that case.