diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml
new file mode 100644
index 0000000..80dc447
--- /dev/null
+++ b/.github/workflows/pages.yml
@@ -0,0 +1,68 @@
+# This workflow uses actions that are not certified by GitHub.
+# They are provided by a third-party and are governed by
+# separate terms of service, privacy policy, and support
+# documentation.
+
+# Sample workflow for building and deploying a Jekyll site to GitHub Pages
+name: Deploy Jekyll site to Pages
+
+on:
+ push:
+ branches: ["docs"]
+
+ # Allows you to run this workflow manually from the Actions tab
+ workflow_dispatch:
+
+# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
+permissions:
+ contents: read
+ pages: write
+ id-token: write
+
+# Allow one concurrent deployment
+concurrency:
+ group: "pages"
+ cancel-in-progress: true
+
+jobs:
+ # Build job
+ build:
+ runs-on: ubuntu-latest
+ defaults:
+ run:
+ working-directory: docs
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ - name: Setup Ruby
+ uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: '3.3' # Not needed with a .ruby-version file
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
+ cache-version: 0 # Increment this number if you need to re-download cached gems
+ working-directory: '${{ github.workspace }}/docs'
+ - name: Setup Pages
+ id: pages
+ uses: actions/configure-pages@v5
+ - name: Build with Jekyll
+ # Outputs to the './_site' directory by default
+ run: bundle exec jekyll build --baseurl "${{ steps.pages.outputs.base_path }}"
+ env:
+ JEKYLL_ENV: production
+ - name: Upload artifact
+ # Automatically uploads an artifact from the './_site' directory by default
+ uses: actions/upload-pages-artifact@v3
+ with:
+ path: docs/_site/
+
+ # Deployment job
+ deploy:
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
+ runs-on: ubuntu-latest
+ needs: build
+ steps:
+ - name: Deploy to GitHub Pages
+ id: deployment
+ uses: actions/deploy-pages@v4
diff --git a/docs/.gitignore b/docs/.gitignore
new file mode 100644
index 0000000..918de83
--- /dev/null
+++ b/docs/.gitignore
@@ -0,0 +1,6 @@
+_site
+.sass-cache
+.jekyll-cache
+.jekyll-metadata
+vendor
+Gemfile.lock
diff --git a/docs/404.html b/docs/404.html
new file mode 100644
index 0000000..086a5c9
--- /dev/null
+++ b/docs/404.html
@@ -0,0 +1,25 @@
+---
+permalink: /404.html
+layout: default
+---
+
+
+
+
+
404
+
+
Page not found :(
+
The requested page could not be found.
+
diff --git a/docs/Gemfile b/docs/Gemfile
new file mode 100644
index 0000000..6e2d920
--- /dev/null
+++ b/docs/Gemfile
@@ -0,0 +1,35 @@
+source "https://rubygems.org"
+# Hello! This is where you manage which Jekyll version is used to run.
+# When you want to use a different version, change it below, save the
+# file and run `bundle install`. Run Jekyll with `bundle exec`, like so:
+#
+# bundle exec jekyll serve
+#
+# This will help ensure the proper Jekyll version is running.
+# Happy Jekylling!
+#gem "jekyll", "~> 4.3.4"
+# This is the default theme for new Jekyll sites. You may change this to anything you like.
+# gem "minima", "~> 2.5"
+gem "just-the-docs"
+# If you want to use GitHub Pages, remove the "gem "jekyll"" above and
+# uncomment the line below. To upgrade, run `bundle update github-pages`.
+# gem "github-pages", group: :jekyll_plugins
+gem "github-pages", "~> 232", group: :jekyll_plugins
+# If you have any plugins, put them here!
+group :jekyll_plugins do
+ gem "jekyll-feed", "~> 0.12"
+end
+
+# Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem
+# and associated library.
+platforms :mingw, :x64_mingw, :mswin, :jruby do
+ gem "tzinfo", ">= 1", "< 3"
+ gem "tzinfo-data"
+end
+
+# Performance-booster for watching directories on Windows
+gem "wdm", "~> 0.1", :platforms => [:mingw, :x64_mingw, :mswin]
+
+# Lock `http_parser.rb` gem to `v0.6.x` on JRuby builds since newer versions of the gem
+# do not have a Java counterpart.
+gem "http_parser.rb", "~> 0.6.0", :platforms => [:jruby]
diff --git a/docs/_config.yml b/docs/_config.yml
new file mode 100644
index 0000000..c486523
--- /dev/null
+++ b/docs/_config.yml
@@ -0,0 +1,61 @@
+# Welcome to Jekyll!
+#
+# This config file is meant for settings that affect your whole blog, values
+# which you are expected to set up once and rarely edit after that. If you find
+# yourself editing this file very often, consider using Jekyll's data files
+# feature for the data you need to update frequently.
+#
+# For technical reasons, this file is *NOT* reloaded automatically when you use
+# 'bundle exec jekyll serve'. If you change this file, please restart the server process.
+#
+# If you need help with YAML syntax, here are some quick references for you:
+# https://learn-the-web.algonquindesign.ca/topics/markdown-yaml-cheat-sheet/#yaml
+# https://learnxinyminutes.com/docs/yaml/
+#
+# Site settings
+# These are used to personalize your new site. If you look in the HTML files,
+# you will see them accessed via {{ site.title }}, {{ site.email }}, and so on.
+# You can create any custom variable you would like, and they will be accessible
+# in the templates via {{ site.myvariable }}.
+
+title: Plutus-Bench Documentation
+#email: your-email@example.com
+description: >- # this means to ignore newlines until "baseurl:"
+ Test and benchmark Plutus Smart Contracts. This project enables you to construct
+ entire smart contract transactions against a mock environment, and measure the
+ correctness (i.e. unit test) and performance of your smart contracts.
+baseurl: "" # the subpath of your site, e.g. /blog
+url: "" # the base hostname & protocol for your site, e.g. http://example.com
+
+# Build settings
+theme: just-the-docs
+plugins:
+ - jekyll-feed
+
+# Exclude from processing.
+# The following items will not be processed, by default.
+# Any item listed under the `exclude:` key here will be automatically added to
+# the internal "default list".
+#
+# Excluded items can be processed by explicitly listing the directories or
+# their entries' file path in the `include:` list.
+#
+# exclude:
+# - .sass-cache/
+# - .jekyll-cache/
+# - gemfiles/
+# - Gemfile
+# - Gemfile.lock
+# - node_modules/
+# - vendor/bundle/
+# - vendor/cache/
+# - vendor/gems/
+# - vendor/ruby/
+
+
+nav_external_links:
+ - title: MockFrost API
+ url: https://mockfrost.dev/redoc
+ hide_icon: false
+ opens_in_new_tab: false
+
diff --git a/docs/_posts/2025-01-21-welcome-to-jekyll.markdown b/docs/_posts/2025-01-21-welcome-to-jekyll.markdown
new file mode 100644
index 0000000..132c53d
--- /dev/null
+++ b/docs/_posts/2025-01-21-welcome-to-jekyll.markdown
@@ -0,0 +1,29 @@
+---
+layout: post
+title: "Welcome to Jekyll!"
+date: 2025-01-21 11:52:59 +0000
+categories: jekyll update
+---
+You’ll find this post in your `_posts` directory. Go ahead and edit it and re-build the site to see your changes. You can rebuild the site in many different ways, but the most common way is to run `jekyll serve`, which launches a web server and auto-regenerates your site when a file is updated.
+
+Jekyll requires blog post files to be named according to the following format:
+
+`YEAR-MONTH-DAY-title.MARKUP`
+
+Where `YEAR` is a four-digit number, `MONTH` and `DAY` are both two-digit numbers, and `MARKUP` is the file extension representing the format used in the file. After that, include the necessary front matter. Take a look at the source for this post to get an idea about how it works.
+
+Jekyll also offers powerful support for code snippets:
+
+{% highlight ruby %}
+def print_hi(name)
+ puts "Hi, #{name}"
+end
+print_hi('Tom')
+#=> prints 'Hi, Tom' to STDOUT.
+{% endhighlight %}
+
+Check out the [Jekyll docs][jekyll-docs] for more info on how to get the most out of Jekyll. File all bugs/feature requests at [Jekyll’s GitHub repo][jekyll-gh]. If you have questions, you can ask them on [Jekyll Talk][jekyll-talk].
+
+[jekyll-docs]: https://jekyllrb.com/docs/home
+[jekyll-gh]: https://github.com/jekyll/jekyll
+[jekyll-talk]: https://talk.jekyllrb.com/
diff --git a/docs/assets/plutus-bench.png b/docs/assets/plutus-bench.png
new file mode 100644
index 0000000..f6b76e3
Binary files /dev/null and b/docs/assets/plutus-bench.png differ
diff --git a/docs/index.md b/docs/index.md
new file mode 100644
index 0000000..2128901
--- /dev/null
+++ b/docs/index.md
@@ -0,0 +1,26 @@
+---
+layout: home
+title: About
+nav_order: 1
+---
+
+
+

+
Plutus-Bench
+
+
+
+Test and benchmark Plutus Smart Contracts.
+This project enables you to construct entire smart contract transactions against a mock environment, and measure the correctness (i.e. unit test) and performance of your smart contracts.
+
+Plutus Bench creates a mock ledger with an arbitrary UTxO set specified by the user.
+It then hosts a mock blockfrost API to interact with the ledger, supporting popular off-chain tooling
+like [translucent](https://github.com/antibody-cardano/translucent) and [pycardano](https://pycardano.readthedocs.io/en/latest/).
+
+> Note: Plutus Bench is currently a Work In Progress, and is not yet ready for production use.
+
+### Why Plutus Bench?
+
+- **Compatability**: Plutus Bench is written in Python, and is compatible with popular off-chain tooling relying on BlockFrost APIs. Ogmios mocking is also planned.
+- **Holistic Testing**: Plutus Bench allows you to test the entire lifecycle of a smart contract, from minting to consuming, in a single test.
+- **Simple**: Plutus Bench is designed to be simple to use, and easy to integrate with your existing infrastructure.
\ No newline at end of file
diff --git a/docs/installation.md b/docs/installation.md
new file mode 100644
index 0000000..e26c946
--- /dev/null
+++ b/docs/installation.md
@@ -0,0 +1,20 @@
+---
+title: Installation
+permalink: /install/
+nav_order: 2
+---
+
+
+
Installation
+
+
+Plutus-Bench is currently not available via any package managers.
+Cloning the github Repo and manually installing with pip is the current recommended method:
+
+```bash
+# clone the plutus-bench package
+git clone https://github.com/OpShin/plutus-bench.git
+cd plutus-bench
+# install the package with pip
+pip install .
+```
diff --git a/docs/usage/_python_api.md b/docs/usage/_python_api.md
new file mode 100644
index 0000000..40d19ed
--- /dev/null
+++ b/docs/usage/_python_api.md
@@ -0,0 +1,125 @@
+---
+layout: page
+title: Usage
+permalink: /usage/
+---
+
+
+
Usage
+
+Generally the workflow is as follows:
+
+- Create a new session with the `/session/create` endpoint. You receive a session ID.
+- Initialize a BlockFrost client in your off-chain code, and point it to the mock server. The base url is `http://localhost:8000//api/v1`. Project id is not required.
+
+That's it! You can now interact with the mock ledger using the BlockFrost client.
+
+You may further manipulate the ledger using the `//ledger` endpoints.
+
+
+
+
+
CMD Mockfrost server
+
+
+A local mockfrost server can be started with the following command
+```bash
+uvicorn plutus_bench.mockfrost.server:app
+```
+After running these commands, a mock blockfrost server will be running on `http://localhost:8000`.
+Head to `http://localhost:8000/docs` to see the API documentation.
+
+
+
Python Mockfrost server
+
+A local mockfrost server can be started from within python:
+```python
+import uvicorn
+from plutus_bench.mockfrost.server import app
+
+uvicorn.run(app, port=8000)
+```
+
+However, in the context of Unit testing the following is recommended Usage.
+
+
+```python
+from multiprocessing import Process
+from time import sleep
+import pytest
+import uvicorn
+from plutus_bench.mockfrost.server import app
+
+own_path = pathlib.Path(__file__)
+
+def run_server():
+ uvicorn.run(app, port=8000)
+
+@pytest.fixture
+def server():
+ proc = Process(target=run_server, args=(), daemon=True)
+ proc.start()
+ sleep(1) # Wait for server to start
+ yield
+ proc.kill() # Cleanup after test
+
+
+def test_code(server):
+ #test code here
+ ...
+```
+
+
+
Using the Mockfrost server with pycardano
+
+
+The mockfrost server can now be accessed via:
+```python
+from plutus_bench.mockfrost.client import MockFrostClient, MockFrostUser
+
+def test_code(server):
+ client = MockFrostClient(base_url="http://127.0.0.1:8000")
+ session = client.create_session()
+ context = session.chain_context()
+```
+Session is a `plutus_bench.mockfrost.MockFrostSession` instance that provides a python API to manipulate the server:
+```python
+ session.add_txout(
+ pycardano.TransactionOutput(address=..., amount=...,),
+ )
+
+```
+
+
+The `context` created above is a `pycardano.BlockFrostChainContext` instance pointing towards your mockfrost server:
+```python
+ # get list of all utxos
+ utxos = context.utxos(address=...)
+ # create and submit pycardano transactions
+ txbuilder = pycardano.TransactionBuilder(context=context)
+ ...
+ # build transaction
+ ...
+ tx = txbuilder.build_and_sign(...)
+ context.submit(tx)
+```
+
+
+
+
+The `plutus_bench.mockfrost.MockFrostUser` class can be used to create mock users on the server:
+
+```python
+ # Create and fund a user
+ user = MockFrostUser(session)
+ fund(100_000_000)
+
+ # Return list of utxos for user
+ utxos = user.utxos()
+
+ # User class holds all required keys and address.
+ s, v, a = user.signing_key, user.verification_key, user.address
+```
+
+
+
diff --git a/docs/usage/index.md b/docs/usage/index.md
new file mode 100644
index 0000000..8f0a76e
--- /dev/null
+++ b/docs/usage/index.md
@@ -0,0 +1,17 @@
+---
+title: Usage
+nav_order: 3
+permalink: /usage/
+---
+
+# Usage
+
+
+Generally the workflow is as follows:
+
+- Create a new session with the `/session/create` endpoint. You receive a session ID.
+- Initialize a BlockFrost client in your off-chain code, and point it to the mock server. The base url is `http://localhost:8000//api/v1`. Project id is not required.
+
+That's it! You can now interact with the mock ledger using the BlockFrost client.
+
+You may further manipulate the ledger using the `//ledger` endpoints.
\ No newline at end of file
diff --git a/docs/usage/mock_python_client.md b/docs/usage/mock_python_client.md
new file mode 100644
index 0000000..4911506
--- /dev/null
+++ b/docs/usage/mock_python_client.md
@@ -0,0 +1,128 @@
+---
+title: Python Client and API
+parent: Usage
+nav_order: 2
+---
+
+# Python Mockfrost Client
+{: .no_toc}
+
+## Table of contents
+{: .no_toc .text-delta}
+
+1. TOC
+{:toc}
+
+## Connect to the server {#client}
+Given a [Mockfrost Server]({% link usage/mock_server.md %}) running on the default address `http://127.0.0.1:8000`, a Mockfrost client can be configured to connect to it as follows:
+```python
+from plutus_bench.mockfrost.client import MockFrostClient, MockFrostUser
+
+def test_code(server):
+ # Create client and point it towards local mockfrost address
+ client = MockFrostClient(base_url="http://127.0.0.1:8000")
+
+ # The client can be used to create a plutus_bench.mockfrost.MockFrostSession
+ # This can be used to directly manipulate your mock chain
+ session = client.create_session()
+
+ # We can create a pycardano.BlockFrostChainContext from the session.
+ # You should be able to interact with the local mockfrost session though the chain context
+ # the same way you interact with testnet or mainnet
+ context = session.chain_context()
+```
+
+## MockFrostSession
+The `session` object [created above](#client) with a `client.create_session()` call is a `plutus_bench.mockfrost.MockFrostSession` instance.
+This creates a unique blockchain state on the mockfrost server accessed via the session ID with the base url `http://localhost:8000//api/v0`.
+The session ID is held as the attribute `session.session_id`.
+
+The MockFrostSession instance provides a python API to manipulate the ledger.
+UTxOs can be added to the mock ledger in two ways:
+```python
+ session.add_utxo(
+ pycardano.UTxO(
+ input = pycardano.TransactionInput(transaction_id=..., index=...),
+ output = pycardano.TransactionOutput(address=..., amount=...),
+ )
+ )
+ #Alternatively if the input does not matter:
+ session.add_txout(
+ pycardano.TransactionOutput(address=..., amount=...,),
+ )
+```
+
+UTxO's can be removed from the ledger via the transaction input:
+```python
+ session.del_txout(
+ pycardano.TransactionInput(transaction_id..., index=...),
+ )
+```
+
+The slot number of the mock ledger may be directly set using `set_slot`:
+```python
+ session.set_slot(71_071_542)
+```
+
+Additionally, for testing staking it is possible to register a mock pool to delegate to and manually distribute rewards:
+```python
+ session.add_mock_pool(pycardano.pool_params.PoolId(...))
+ session.distribute_rewards(100_000_000) # each correctly delegated account receives this reward
+```
+
+
+
+
+
+
+## Pycardano ChainContext
+
+The `context` object created [above](#client) is a `pycardano.BlockFrostChainContext` instance pointing towards a mockfrost session on your server.
+This should be used to interact with the local network as you would with testnet or mainnet:
+```python
+ # get parameters and properties
+ print(f'Protocol: {context.protocol_param}')
+ print(f'Genesis: {context.genesis_param}')
+ print(f'Epoch: {context.epoch}')
+ print(f'Slot: {context.last_block_slot}')
+ print(f'Network: {context.network}')
+
+ # Retrieve all utxos beloning to an address
+ utxos = context.utxos(address=...)
+
+ # create and submit pycardano transactions
+ txbuilder = pycardano.TransactionBuilder(context=context)
+ ...
+ ...
+ tx = txbuilder.build_and_sign(...)
+ context.submit(tx)
+```
+
+## Mock Users
+
+The `plutus_bench.mockfrost.MockFrostUser` class can be used to create mock users on the server:
+
+```python
+ from plutus_bench.mockfrost import MockFrostUser
+ # Create and fund a user
+ user = MockFrostUser(session)
+ fund(100_000_000)
+
+ # Return list of utxos for user
+ utxos = user.utxos()
+
+ # User class holds all required keys and address.
+ s, v, a = user.signing_key, user.verification_key, user.address
+```
+
+## Mock Pool
+For staking you need a mock pool with which to delegate to. This can be most easily achieved with the `plutus_bench.mockfrost.MockFrostPool`:
+```python
+ from plutus_bench.mockfrost import MockFrostPool
+ # Create Pool
+ stake_pool = MockFrostPool(session)
+
+ # distribute rewards to delegated accounts
+ session.distribute_rewards(100_000_000)
+
+
diff --git a/docs/usage/mock_server.md b/docs/usage/mock_server.md
new file mode 100644
index 0000000..6a7c3f9
--- /dev/null
+++ b/docs/usage/mock_server.md
@@ -0,0 +1,67 @@
+---
+title: Mockfrost Server
+parent: Usage
+nav_order: 1
+---
+# MockFrost Server
+
+{: .no_toc}
+## Table of contents
+{: .no_toc .text-delta}
+
+1. TOC
+{:toc}
+
+## CMD
+
+
+
+A local mockfrost server can be started with the following command
+```bash
+uvicorn plutus_bench.mockfrost.server:app
+```
+After running these commands, a mock blockfrost server will be running on `http://localhost:8000`.
+Head to `http://localhost:8000/docs` to see the API documentation.
+
+
+
+
+## Python
+
+A local mockfrost server can be started from within python:
+```python
+import uvicorn
+from plutus_bench.mockfrost.server import app
+
+uvicorn.run(app, port=8000)
+```
+
+For integration into unit testing we would recommend the following style:
+
+
+```python
+from multiprocessing import Process
+from time import sleep
+import pytest
+import uvicorn
+from plutus_bench.mockfrost.server import app
+
+own_path = pathlib.Path(__file__)
+
+def run_server():
+ uvicorn.run(app, port=8000)
+
+@pytest.fixture
+def server():
+ proc = Process(target=run_server, args=(), daemon=True)
+ proc.start()
+ sleep(1) # Wait for server to start
+ yield
+ proc.kill() # Cleanup after test
+
+
+def test_contracts(server):
+ # test your contracts here
+ ...
+```
+