{"id":15061494,"url":"https://github.com/cavaunpeu/solsim","last_synced_at":"2025-10-22T21:38:44.622Z","repository":{"id":44572513,"uuid":"451873997","full_name":"cavaunpeu/solsim","owner":"cavaunpeu","description":"The Solana complex systems simulator.","archived":false,"fork":false,"pushed_at":"2022-02-07T16:00:29.000Z","size":1579,"stargazers_count":16,"open_issues_count":0,"forks_count":2,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-18T18:52:24.064Z","etag":null,"topics":["complex-systems","simulation","solana"],"latest_commit_sha":null,"homepage":"https://cavaunpeu.github.io/solsim","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cavaunpeu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-01-25T12:46:21.000Z","updated_at":"2025-01-10T03:16:04.000Z","dependencies_parsed_at":"2022-09-19T09:30:27.826Z","dependency_job_id":null,"html_url":"https://github.com/cavaunpeu/solsim","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cavaunpeu%2Fsolsim","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cavaunpeu%2Fsolsim/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cavaunpeu%2Fsolsim/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cavaunpeu%2Fsolsim/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cavaunpeu","download_url":"https://codeload.github.com/cavaunpeu/solsim/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248190484,"owners_count":21062279,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["complex-systems","simulation","solana"],"created_at":"2024-09-24T23:20:16.109Z","updated_at":"2025-10-22T21:38:44.560Z","avatar_url":"https://github.com/cavaunpeu.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# solsim\n\n\u003cdiv align=\"center\"\u003e\n    \u003cimg src=\"https://raw.githubusercontent.com/cavaunpeu/solsim/main/img/logo.png\" width=\"70%\" height=\"70%\"\u003e\n\u003c/div\u003e\n\n---\n\n\u003c!-- Badges --\u003e\n\n[![Discord Chat](https://img.shields.io/discord/889577356681945098?color=blueviolet)](https://discord.gg/sxy4zxBckh)\n[![Downloads](https://pepy.tech/badge/solsim)](https://pepy.tech/project/solsim)\n\n\u003c!-- Tests and Lint Badges --\u003e\n\n\u003cdiv\u003e\n\u003cimg alt=\"Tests\" src=\"https://github.com/cavaunpeu/solsim/actions/workflows/tests.yml/badge.svg\"\u003e\n\u003cimg alt=\"Lint\" src=\"https://github.com/cavaunpeu/solsim/actions/workflows/lint.yml/badge.svg\"\u003e\n\u003c/div\u003e\n\n---\n\n## Introduction\n\nsolsim is the Solana complex systems simulator. It simulates behavior of dynamical systems—DeFi protocols, DAO governance, cryptocurrencies, and more—built on the [Solana](https://solana.com/) blockchain.\n\n## Philosophy\n\nDefine your system how you see fit.\n\nsolsim will simulate its behavior and collect its results in a structured, straightforward manner.\n\n## Usage\n\n1. Implement `initial_step` and `step` methods.\n2. From each, return the current state, i.e. a dictionary mapping variables to current values.\n3. Specify the variables you'd like to \"watch.\"\n4. Instantiate a Simulation, call `.run()`.\n5. Receive a [pandas](https://pandas.pydata.org/) DataFrame containing values of \"watched\" variables at each step in time.\n\n### With Solana\n\n```python\nfrom anchorpy import Context\nfrom solana.keypair import Keypair\nfrom solsim.simulation import Simulation\n\nclass SomeSolanaSystem(BaseSolanaSystem):\n    def __init__(self):\n        super().__init__(\"path/to/workspace\")\n        self.account = Keypair()\n        self.pubkey = self.account.public_key\n        self.program = self.workspace[\"my_anchor_program\"]  # solsim gives a Anchor program workspace (self.workspace).\n\n    async def initial_step(self):\n        self.program.rpc[\"initialize\"]()  # Make RPC calls to your Anchor program.\n        await self.client.request_airdrop(self.pubkey, 10)  # solsim gives you a Solana API client (self.client).\n        return {\"balance\": await self.client.get_balance(self.pubkey)}\n\n    async def step(self, state, history):\n        self.program.rpc[\"submit_uniswap_trade\"](\n            ctx=Context(accounts={\"account\": self.pubkey}, signers=[self.account])\n        )\n        return {\"balance\": await self.client.get_balance(self.account)}\n\n\nsimulation = Simulation(system=SomeSolanaSystem(), watchlist=(\"balance\"))\nresults = simulation.run(steps_per_run=5)  # Returns pandas DataFrame of results.\n```\n\n### Without Solana\n\n```python\nclass SomeSystem(BaseSystem):\n    def __init__(self, population):\n        self.pop = population\n\n    def initial_step(self):\n        return {\"population\": self.pop}\n\n    def step(self, state, history):\n        return {\"population\": state[\"population\"] * 1.1}\n\n\nsimulation = Simulation(system=SomeSystem(), watchlist=(\"population\"))\nresults = simulation.run(steps_per_run=5)\n```\n\n## CLI\n\nOptionally run your simulations via CLI. Instead of calling `simulation.run()` in your code:\n\n1. Call `simulation.cli()`.\n2. Run your simulation as e.g. `python path/to/file.py run --num-runs 3`.\n\n## Results Explorer\n\nsolsim gives you a streamlit app to explore results, e.g.\n\n\u003cdiv\u003e\n    \u003cimg src=\"https://raw.githubusercontent.com/cavaunpeu/solsim/main/img/results_explorer_app.png\"\u003e\n\u003c/div\u003e\n\nTo automatically start this app following simulation, invoke one of the following:\n\n- `simulation.run(visualize_results=True)`\n- `--viz-results` flag in the CLI runner, e.g. `python path/to/file.py run --viz-results`\n\n## Installation\n\nFirst, install [Anchor](https://project-serum.github.io/anchor/getting-started/installation.html#install-rust).\n\n### Library\n\n```sh\npip install solsim\n```\n\n### Development\n\nInstall [poetry](https://python-poetry.org/). Then,\n\n```sh\ngit clone --recurse-submodules https://github.com/cavaunpeu/solsim.git\ncd solsim\npoetry install\npoetry shell\n```\n\n## Detailed Usage\n\n### With Solana\n\nFirst, write your Solana program. solsim prefers you do this in [Anchor](https://project-serum.github.io/anchor/getting-started/introduction.html). Then,\n\n1. Write a system class that inherits from `BaseSolanaSystem`.\n2. Call `super().__init__(\"path/to/program\")` in its `__init__`.\n3. Implement `initial_step` and `step` methods. (Since you'll interact with Solana asynchronously, these methods should be `async`.)\n\nIn `2.`, solsim exposes the following attributes to your system instance:\n\n- `self.workspace`: IDL clients for the Solana programs that comprise your system (via [anchorpy](https://github.com/kevinheavey/anchorpy)).\n\nFor example, these clients let you interact with your respective programs' RPC endpoints.\n\n- `self.client`: a general Solana client (via [solana-py](https://github.com/michaelhly/solana-py)).\n\nThis client lets you interact with Solana's RPC endpoints. Documentation [here](https://michaelhly.github.io/solana-py/api.html#).\n\nFinally,\n\n1. Define a `watchlist`: variables (returned in `initial_step` and `step`) you'd like to \"watch.\"\n2. Instantiate and run your simulation, e.g. `Simulation(MySystem(), watchlist).run(steps_per_run=10)`.\n\n### Without Solana\n\n1. Write a system class that inherits from `BaseSystem`.\n2. Implement `initial_step` and `step` methods.\n3. Define a `watchlist`.\n4. Instantiate and run your simulation.\n\n## Examples\n\n### Drunken Escrow\n\nAgents are randomly paired to exchange random amounts of `foo_coin` and `bar_coin` via an Anchor escrow contract in each timestep.\n\n- Run: `python -m examples.drunken_escrow`.\n- Code: [here](https://github.com/cavaunpeu/solsim/tree/main/examples/drunken_escrow).\n- Expected output (numbers may vary):\n\n```\n(.venv) ➜  solsim git:(main) python -m examples.drunken_escrow\n👆 Starting Solana localnet cluster (~5s) ...\n🟢 run: 0 | step: 100%|███████████████████████████████████████████████████████████████████████████████████| 4/4 [00:34\u003c00:00,  8.60s/it]\n👇 Terminating Solana localnet cluster ...\n   step  run  mean_balance_spread  mean_swap_amount  num_swaps\n0     0    0            17.333333         41.333333          3\n1     1    0            22.000000          4.666667          3\n2     2    0            40.000000         25.666667          3\n3     3    0            44.000000         14.666667          3\n```\n\n### Lotka-Volterra\n\nThe Lotka-Volterra model is a classic dynamical system in the field of ecology that tracks the evolution of interdependent predator and prey populations.\n\n- Run: `python -m examples.lotka_volterra`.\n- Code: [here](https://github.com/cavaunpeu/solsim/tree/main/examples/lotka_volterra).\n- Expected output:\n\n```\n(.venv) ➜  solsim git:(main) python -m examples.lotka_volterra\n🟢 run: 0 | step: 100%|████████████████████████████████████████████████████████████████████████████████| 4/4 [00:00\u003c00:00, 70492.50it/s]\n   step  run  food_supply  population_size\n0     0    0     1000.000            50.00\n1     1    0      995.000            60.00\n2     2    0      989.000            69.95\n3     3    0      982.005            79.84\n```\n\nThis example is inspired by [cadCAD Edu](https://www.cadcad.education/).\n\n## Inspiration\n\nsolsim humbly builds on the shoulders of the giants that are [cadCAD](https://github.com/cadCAD-org/cadCAD) and [tokenspice](https://github.com/tokenspice/tokenspice), among others.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcavaunpeu%2Fsolsim","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcavaunpeu%2Fsolsim","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcavaunpeu%2Fsolsim/lists"}