```bash
#  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
#  ░░     ░░░       ░░░     ░░░      ░░░░  ░░░  ░░      ░░░       ░░       ░░      ░░      ░░░
#  ▒  ▒▒▒▒▒▒▒▒▒  ▒▒▒▒▒  ▒▒▒  ▒▒  ▒▒▒  ▒▒▒  ▒▒  ▒▒▒  ▒▒▒  ▒▒▒▒▒  ▒▒▒▒▒▒  ▒▒▒▒▒  ▒▒▒▒▒▒  ▒▒▒  ▒▒
#  ▓▓     ▓▓▓▓▓  ▓▓▓▓▓  ▓▓▓  ▓▓     ▓▓▓▓▓    ▓▓▓▓▓      ▓▓▓▓▓▓  ▓▓▓▓▓▓  ▓▓▓▓▓    ▓▓▓▓      ▓▓▓
#  ██████  ████  █████       ██  ███  ███  ██  ███  ███  █████  ██████  █████  ██████  ███  ██
#  ██     █████  █████  ███  ██  ████  ██  ███  ██      ███       ████  █████      ██  ████  █
#  ███████████████████████████████████████████████████████████████████████████████████████████
```
> Expanding the Starknet tooling ecosystem.

![Github Actions](https://github.com/astraly-labs/starkbiter/workflows/test/badge.svg)
![Twitter Badge](https://badgen.net/badge/icon/twitter?icon=twitter&label)(https://twitter.com/PragmaOracle)

## Overview
> **Starkbiter** is a framework for orchestrating event based agentic simulations on top of Starknet Devnet sandbox.

Starkbiter provides a Full JSON-RPC Starknet Node capabilities with additional methods to control block production, contract and account deployments and declaration. It integrates deeply with starknet-devnet and starknet-rs types crates allowing for seamless integration for all the tooling that depends on those. Thus, it also provides additional layer of well known contract bindings generated by [cainome](https://github.com/cartridge-gg/cainome).

The primary use of Starkbiter is to probe the mechanism security of smart contracts, and perform advanced economic modelling.

---

The Starkbiter workspace has five crates:
- `starkbiter`: The bin that exposes a command line interface for contract bindings.
- `starkbiter-core`: A lib containing the core logic for the Starkbiter framework, including the `StarkbiterMiddleware` discussed before, and the `Environment`, our sandbox.
- `starkbiter-engine`: A lib that provides abstractions for building simulations, agents, and behaviors.
- `starkbiter-macros`: A lib crate that contains the macros used to simplify development with Starkbiter.
- `starkbiter-bindings`: A lib crate containing bindings for utility smart contracts used for testing and development.

## WIP

- [ ] non-blocking event polling
- [x] bin docs
- [x] core docs
- [x] main readme
- [ ] docs docs
    - [x] getting started
    - [ ] usage
    - [x] index
- [ ] benchmarks
- [ ] python bindings
- [x] more test cases
- [ ] coverage report
- [x] support for replaying mainnet transactions mixing them with simulated ones.
- [x] github workflows revival
- [ ] contribute to cainome and remove fork dep
- [ ] contribute to starknet-rs and remove fork dep + Fix generic Runtime error with more specific errors from within Provider
- [ ] contribute to starknet-devnet and remove fork dep
- [x] test that toml config parameters for forking work
- [x] contract execution logging and traces from Devnet
- [ ] test for simultaneous connection usage by different contracts.


## Book
TODO: Does not exist yet

## Motivation
Starkbiter was adapted from [Arbiter](https://github.com/harnesslabs/arbiter) code to allow you to work with smart contracts in a stateful sandbox and thus design agents that can be used alongside the contracts.
This gives you many capabilities.
For instance, smart contract engineers must test their contracts against various potentially adversarial environments and parameters instead of relying on static and stateless testing.

In Decentralized Finance (DeFi), a wide array of complex decentralized applications can use the testing described above. Still, implicit financial strategies also encompass many agents and parameterizations.
A financial engineer may want to test their strategies against thousands of market conditions, contract settings, shocks, and autonomous or random AI agents while ensuring their approach isn't vulnerable to bytecode-level exploits.
Likewise, the same engineer may want to develop searcher agents, solver agents, or other autonomous agents that can be run on the blockchain.

## Working with the Starkbiter Framework
To work with Starkbiter, you must have Rust installed on your machine.
You can install Rust by following the instructions [here](https://www.rust-lang.org/tools/install).
It will also be helpful to get the `cargo-generate` package, which you can install by doing:
```bash
cargo install cargo-generate
```

### Examples
We have an example that will run what we have set up in a template.
To run this, you can clone the repository and update the submodules:
```bash
git clone https://github.com/astraly-labs/starkbiter
cd starkbiter
```

From here, you can now try running the following from the clone's root directory:
```bash
cargo run --example minter
```
This command will enter the template CLI and show you the commands and flags.

To run the `ModifiedCounter.sol` example and see some logging, try:
```bash
cargo run --example minter simulate ./examples/minter/config.toml -vvvv
```
This sets the log level to `trace` so you can see what's happening internally.

### Binary
To install the Starkbiter binary, run:
```bash
cargo install starkbiter
```
This will install the Starkbiter binary on your machine. You can then run `starkbiter --help` to see that Starkbiter was correctly installed and see the help menu.

### Bindings
You can put your compiled sierra 1.0 contract jsons in the `contracts/` directory of your templated project, you'll need to run:

```bash
starkbiter bind
```

to generate rust bindings and you are good to go. You can use those within your contracts now.
Starkbiter uses `cainome` to generate rust bindings and in turn `cainome` relies on starknet-rs account abstraction implementation. You can easily generate an account using `create_single_owner_account` method of the environment (and middleware) and pass it to create an instance of the contract you you want to execute.

### Forking
To fork a state of an Starknet network, you need to specify fork parameters upon instantiating environment. Fork is being initialised lazily, this mechanics is inherited from starknet devnet implementation.

```rust
let env = Environment::builder()
    .with_chain_id(chain_id.into())
    .with_fork(
        Url::from_str("http://json-rpc-provider-to-fork-from:1234").unwrap(),
        1000, // Block number to fork from
        Some(Felt::from_str("0xblock_hash").unwrap()),
    )
    .build();
```

This will instantiate environment which will upon request fetch missing bits of state and store those in memory, locally. Current implementation implies we need to have endpoint rpc endpoint available during the simulation.

## Cargo Docs

To see the Cargo docs for the Starkbiter crates, please visit the following:
- [`starkbiter`](https://docs.rs/crate/starkbiter/)
- [`starkbiter-bindings`](https://docs.rs/crate/starkbiter-bindings/)
- [`starkbiter-core`](https://docs.rs/starkbiter-core/)
- [`starkbiter-macros`](https://docs.rs/starkbiter-macros/)
- [`starkbiter-engine`](https://docs.rs/starkbiter-engine/)

You will find each of these on crates.io.

## Benchmarks
In `starkbiter-core`, we have a a small benchmarking suite that currently is under WIP.
TODO: benchmarks. What are we benchmarking against?

## Testing

If you contribute, please write tests for any new code you write. To run the tests, you can run the following:

```bash
cargo test --all --all-features
```

## Contributing

See our [Contributing Guidelines](https://github.com/astraly-labs/starkbiter/blob/main/.github/CONTRIBUTING.md)
