Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
name: Bug report
about: Report a reproducible bug
title: "bug: "
labels: bug
assignees: ""
---

## Description

<!-- A clear and concise description of what the bug is. -->

## Steps to reproduce

<!-- Minimal command sequence or code snippet that triggers the bug. -->

## Expected behaviour

<!-- What you expected to happen. -->

## Actual behaviour

<!-- What actually happened. Include error output, panic messages, or unexpected responses. -->

## Environment

- **OS**: <!-- e.g. Ubuntu 24.04, macOS 15 -->
- **Rust version**: <!-- output of `rustc --version` -->
- **Commit / tag**: <!-- git rev-parse --short HEAD -->
- **Affected crate(s)**: <!-- core / service / cli / jet_plugins -->

## Logs

<!-- Paste relevant logs here. Redact any sensitive data such as private keys. -->

```plaintext
paste here
```

## Additional context

<!-- Anything else that might help diagnose the issue. -->
5 changes: 5 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: Security vulnerability
url: https://github.com/BlockstreamResearch/simplicity-unchained/security/advisories/new
about: Please report security issues privately via GitHub's security advisory feature rather than opening a public issue.
27 changes: 27 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
name: Feature request
about: Propose a new feature or improvement
title: "feat: "
labels: enhancement
assignees: ""
---

## Problem / motivation

<!-- Describe the problem or limitation this feature would address. -->

## Proposed solution

<!-- Describe the change or addition you have in mind. -->

## Affected crate(s)

<!-- Which crate(s) would this touch? core / service / cli / jet_plugins -->

## Alternatives considered

<!-- Have you considered any alternative approaches? Why is this one preferred? -->

## Additional context

<!-- Any relevant background, links to specs, related issues, or prior art. -->
39 changes: 39 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Summary

<!-- Describe what this PR changes and why. -->

## Type of change

- [ ] Bug fix
- [ ] New feature
- [ ] Refactor
- [ ] Documentation
- [ ] Dependency update
- [ ] Other (describe below)

## Affected crates

- [ ] `core`
- [ ] `jet_plugins`
- [ ] `service`
- [ ] `cli`
- [ ] `plugin_tests`
- [ ] CI / tooling

## Checklist

- [ ] `cargo fmt --all` passes
- [ ] `cargo clippy --workspace --all-targets -- -D warnings` passes
- [ ] `cargo test --workspace --all-targets` passes

## Breaking changes

<!-- List any breaking changes to public APIs or behaviour, or write "None". -->

## Testing

<!-- Describe how this was tested, or why no new tests were needed. -->

## Related issues

<!-- Closes #, Refs # -->
120 changes: 120 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# Contributing to Simplicity Unchained

Contributions of all kinds are welcome — bug reports, documentation improvements, and tests.

## Project Structure

The workspace is organised into focused crates. Keep changes scoped to the appropriate crate and discuss cross-crate changes in an issue first.

- [`core`](core/README.md): Simplicity execution engine, Bitcoin/Elements environments, and the dynamic jet loading API.
- [`jet_plugins`](jet_plugins/README.md): Procedural macro that derives the `Jet` trait and C FFI for custom jet plugins.
- [`service`](service/README.md): Axum HTTP service exposing the sign/PSBT, sign/PSET, and key-tweak endpoints.
- [`cli`](cli/README.md): `clap`-based CLI for interacting with the service and accessing ecosystem utilities.
- `plugin_tests/`: Example and integration-test jet plugins for Bitcoin, Elements, and opcode pubkey variants.

## Issues

If this is just a bug report or a feature request, please open an issue first so it can be discussed. PRs for bug fixes are also welcome and can be discussed directly in the PR. However, for larger changes, it is better to open an issue first to discuss the proposed change before implementing it.

### Pull Requests

1. Fork the repository and create a branch from `development`.
2. Make your changes, including tests where applicable.
3. Ensure CI checks pass.
4. Open a PR against `development` describing what was changed and why.
5. Keep PRs focused, one logical change per PR. Split large changes into sequential PRs if needed.

## Coding Conventions

- Run `cargo fmt` before every commit.
- The project targets zero `clippy` warnings with `-D warnings`. Fix all warnings introduced by your changes.
- Use `thiserror` for library errors. Avoid `unwrap()` outside of tests and examples.
- Keep the public API surface minimal. Only `pub` what downstream crates genuinely need, and add `///` doc comments to all new public items.
- Adding a new dependency requires justification. Prefer `[workspace.dependencies]` entries and avoid floating version requirements.
- Add unit tests under a `#[cfg(test)]` module in the same file.

## Adding Custom Jets

Custom jets are the primary extension point. To add a new jet plugin:

1. Create a new crate that depends on `jet_plugins` and `simplicity_unchained_core`, declare it as a `cdylib`:

```toml
# Cargo.toml
[lib]
crate-type = ["cdylib"]
```

2. Define your jet functions matching the expected signature:

```rust
fn my_jet(_dst: &mut CFrameItem, _src: CFrameItem, _env: &BitcoinUnchainedEnv) -> bool {
// return true on success
todo!()
}
```

3. Register them with the `register_jets!` macro:

```rust
use jet_plugins::register_jets;
use simplicity_unchained_core::jets::environments::BitcoinUnchainedEnv;
use hal_simplicity::simplicity::ffi::CFrameItem;

register_jets!(
hal_simplicity::simplicity::jet::Core, // base jet set
BitcoinUnchainedEnv, // environment type
"my_jet_name" => my_jet, b"h", b"h", // (name, fn, source_type, target_type)
);
```

4. Pass the compiled `.so`/`.dylib` path to the core runner via the dynamic loading API. See `core/src/jets/jet_dyn.rs` and `cli/assets/custom_jet_dlls/` for reference.

## Running the Service Locally

```bash
cd service
cargo run --quiet -- start
```

The service reads `config.toml` from the current directory by default. You can point it at a custom file with `--config`:

```bash
cargo run --quiet -- start --config path/to/your/config.toml
```

To exercise CLI commands against the running service, use the demo scripts:

```bash
# Bitcoin regtest demo
cd cli && ./scripts/demo_btc.sh

# Elements / Liquid testnet demo
cd cli && ./scripts/demo_elements.sh
```

## Docker

The multi-stage `Dockerfile` builds the `service` binary. To build and run:

```bash
docker build -t simplicity-unchained-service .
docker run -p 8080:8080 simplicity-unchained-service
```

The container runs as a non-root user (`uid=1000`). Ensure mounted config files are readable by that user.

## Reporting Bugs

Open a GitHub issue including:

1. What happened vs. what you expected.
2. A minimal command sequence or code snippet to reproduce the issue.
3. Your OS, Rust version (`rustc --version`), and commit hash.
4. Relevant error output with sensitive data redacted.

For security-sensitive issues, please follow responsible disclosure and contact the maintainers privately before opening a public issue.

## Licence

By contributing to this project you agree that your contributions are released under the [CC0 1.0 Universal](LICENCE) licence, the same licence that covers the project.
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ The primary target is **Bitcoin** (including Bitcoin testnets), with additional
>
> This project is still in active development and conceptualization. It is **not safe for use in production environments** at this time. Features and functionality may change, and there may be critical bugs or incomplete implementations.

## How It Works

See [core/README.md](core/README.md) for a detailed explanation of the unchained model, the taproot tree structure, and the co-signing flow.

## Project Structure

- [`core`](core/README.md): Contains the fundamental logic for executing Simplicity programs, interacting with Bitcoin and Elements environments and interface for loading custom jet implementations from dynamic libraries. (Note: In the future, parts of this logic may be migrated to [hal-simplicity](https://github.com/BlockstreamResearch/hal-simplicity))
Expand All @@ -30,7 +34,7 @@ A live testnet demo is hosted at **[testnet.simplicity-unchained.blockstream.com

### Bitcoin

You can explore the Bitcoin capabilities by running the [Bitcoin demo script](cli/scripts/demo_bitcoin.sh). This demo guides you through:
You can explore the Bitcoin capabilities by running the [Bitcoin demo script](cli/scripts/demo_btc.sh). This demo guides you through:

1. Tweaking a public key with a Simplicity program via the Simplicity Unchained service.
2. Creating a 2-of-2 multisig P2TR address on Bitcoin regtest.
Expand All @@ -40,7 +44,7 @@ You can explore the Bitcoin capabilities by running the [Bitcoin demo script](cl

### Elements / Liquid

The [Elements demo script](cli/scripts/demo.sh) demonstrates the same 2-of-2 multisig co-signing flow on the Liquid Testnet.
The [Elements demo script](cli/scripts/demo_elements.sh) demonstrates the same 2-of-2 multisig co-signing flow on the Liquid Testnet.

To run either demo, follow the instructions in the [CLI readme](cli/README.md).

Expand Down
76 changes: 57 additions & 19 deletions cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,46 +4,84 @@ Command-line interface for communicating with the Simplicity Unchained service a

## Commands

You can easily access command descriptions and information about available arguments by using the `--help` flag with any command. There is no need to duplicate this information here.

```man
A CLI tool for Simplicity Unchained utilities
Use the `--help` flag with any command or subcommand for the full list of arguments.

```plaintext
Usage: simplicity-unchained <COMMAND>

Commands:
address Address operations
keypair Keypair operations
tx Transaction operations
help Print this message or the help of the given subcommand(s)

Options:
-h, --help Print help
address Address operations
keypair Keypair operations
tx Transaction operations (Elements / Liquid)
btc-tx Transaction operations (Bitcoin)
help Print this message or the help of the given subcommand(s)
```

## Demo
### address

- `address multisig` — Generate a P2TR 2-of-2 multisig address from two public keys and a user leaf hash.

### keypair

- `keypair generate` — Generate a new secp256k1 keypair.

You can run the [demo script](scripts/demo.sh) to see example usages of the CLI commands and an example of Simplicity Unchained capabilities.
### tx (Elements / Liquid)

Service supports P2SH, P2WSH and P2TR transaction types.
- `tx create` — Create a PSET from UTXOs.
- `tx sign` — Sign a PSET with one secret key (for local co-signing).
- `tx finalize` — Finalize a PSET into a broadcastable transaction.
- `tx build-csv-leaf` — Build a CSV recovery leaf script from a user pubkey and timelock.
- `tx spend-user-leaf` — Spend the user leaf (Leaf 1) of a P2TR output independently.
- `tx finalize-user-leaf` — Finalize a user leaf PSET into a broadcastable transaction.

Firstly, ensure you have the Simplicity Unchained service running.
### btc-tx (Bitcoin)

- `btc-tx create` — Create a PSBT from UTXOs.
- `btc-tx sign` — Sign a PSBT with one secret key (for local co-signing).
- `btc-tx finalize` — Finalize a PSBT into a broadcastable transaction.
- `btc-tx build-csv-leaf` — Build a CSV recovery leaf script from a user pubkey and timelock.
- `btc-tx spend-user-leaf` — Spend the user leaf (Leaf 1) of a P2TR output independently.
- `btc-tx finalize-user-leaf` — Finalize a user leaf PSBT into a broadcastable transaction.

## Demo

First, ensure the Simplicity Unchained service is running:

```bash
cd service
cargo run --quiet -- start
```

Then, in a separate terminal, navigate to the `cli` directory and execute the demo script:
Then, in a separate terminal, navigate to the `cli` directory and run one of the demo scripts:

### Bitcoin (regtest)

Requires a running `bitcoind` in regtest mode and `bitcoin-cli` in your `PATH`:

```bash
bitcoind -regtest -fallbackfee=0.0002 -txindex=1 -daemon
bitcoin-cli -regtest loadwallet <wallet>
```

```bash
cd cli
./scripts/demo_btc.sh # 2-of-2 co-signing via Simplicity program
./scripts/demo_btc_user_leaf.sh # CSV recovery leaf spend
```

### Elements / Liquid Testnet

Requires `curl` and `jq` in your `PATH`. Transactions are broadcast to Liquid Testnet via the Blockstream API.

```bash
cd cli
./scripts/demo.sh p2sh/p2wsh/p2tr
./scripts/demo_elements.sh # 2-of-2 co-signing via Simplicity program
./scripts/demo_elements_user_leaf.sh # CSV recovery leaf spend
```

> ⚠️ **Warning: Too many requests**
> ⚠️ **Warning: Liquid Testnet Faucet rate limit**
>
> The demo script interacts with the Liquid Testnet Faucet, which imposes a rate limit of 3 requests per minute per IP address. If you exceed this limit, the script may fail. If this happens, please wait at least one minute before running the script again.
> The Elements demo scripts interact with the Liquid Testnet Faucet, which imposes a rate limit. If the script fails due to rate limiting, wait at least one minute before retrying.

## Licence

Expand Down
Binary file modified cli/assets/custom_jet_dlls/libbitcoin.so
Binary file not shown.
Binary file modified cli/assets/custom_jet_dlls/libelements.so
Binary file not shown.
Binary file modified cli/assets/custom_jet_dlls/libopcode_pubkey_bitcoin.so
Binary file not shown.
Binary file modified cli/assets/custom_jet_dlls/libopcode_pubkey_elements.so
Binary file not shown.
Loading
Loading