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
56 changes: 56 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: Publish

on:
workflow_dispatch:
inputs:
dry_run:
description: "Package only; do not publish to crates.io"
required: true
type: boolean
default: true

permissions:
contents: read

concurrency:
group: publish
cancel-in-progress: false

jobs:
publish:
name: Publish crates
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: dtolnay/rust-toolchain@b725eda525362e7cf34af9a7243cac1e3f01a7ec # stable
with:
toolchain: stable
- uses: Swatinem/rust-cache@d1527c8f67ef9af357290475d4af4b0fab8f12e0 # v2
with:
workspaces: "."

- name: Package workspace
run: cargo package --workspace --no-verify

- name: Publish crates in dependency order
if: inputs.dry_run == false
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
run: |
set -euo pipefail

publish() {
echo "Publishing $1"
cargo publish -p "$1" --locked
# Give the crates.io index time to expose the new version before
# dependent crates resolve it.
sleep 30
}

publish devkit-core
publish devkit-config
publish devkit-xdr
publish devkit-rpc
publish devkit-contract
publish devkit-analysis
publish devkit-cli
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ All notable changes to this project are documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added

- `devkit-xdr`: versioned decoded-XDR JSON schema (`schema_version` `1.0`) for
`ScVal`, `TransactionEnvelope`, and `ContractEvent`, an opt-in `raw_xdr`
echo (`--raw`), golden snapshots, and the `docs/XDR.md` and `docs/SCVAL.md`
schema references.

## [0.1.0] - 2026-10-28

First tagged release. Prebuilt binaries for Linux x86_64, macOS arm64, and
Expand Down
27 changes: 25 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ The core works fully **offline** and never requires AI.

- `devkit-core` — shared errors, network profiles, output format.
- `devkit-xdr` — decode `ScVal`, `TransactionEnvelope`, and `ContractEvent` from
base64 XDR into JSON; classify Stellar strkeys; bounded malformed-input
handling.
base64 XDR into a versioned JSON document (`schema_version` 1.0) with an
opt-in `raw_xdr` echo; classify Stellar strkeys; bounded malformed-input
handling. See [docs/XDR.md](docs/XDR.md) and [docs/SCVAL.md](docs/SCVAL.md).
- `devkit-rpc` — endpoint validation, typed protocol layer, deterministic mock
transport, retry policy, and a bounded HTTP JSON-RPC transport.
- `devkit-contract` — non-executing WASM validation, import/export/custom-section
Expand Down Expand Up @@ -71,6 +72,24 @@ stellar-foundry rpc-health https://soroban-testnet.stellar.org
Decode commands accept `-` to read one bounded value from stdin. Exit codes:
`0` success, `2` usage error, `3` runtime/decode error.

## Demo

Run a short tour with captured Soroban testnet data:

```bash
bash demo/run-demo.sh
```

On Windows:

```powershell
pwsh demo/run-demo.ps1
```

The demo decodes a real testnet transaction and event value, inspects a minimal
WASM module, emits SARIF, and optionally checks testnet RPC health. See
[demo/README.md](demo/README.md).

## Scope and limitations

- `contractspecv0` entries are decoded into XDR-JSON definitions with a variant
Expand Down Expand Up @@ -106,8 +125,12 @@ Decode commands accept `-` to read one bounded value from stdin. Exit codes:
- [Architecture](docs/ARCHITECTURE.md)
- [Getting started](docs/GETTING_STARTED.md)
- [CLI reference](docs/CLI.md)
- [XDR JSON schema](docs/XDR.md)
- [SCVal JSON schema](docs/SCVAL.md)
- [Configuration](docs/CONFIGURATION.md)
- [Implemented capabilities](docs/IMPLEMENTED_CAPABILITIES.md)
- [Testnet demo](demo/README.md)
- [Publishing to crates.io](docs/PUBLISHING.md)
- [Memory measurement](docs/MEMORY.md)
- [Testing guide](docs/TESTING.md)
- [Project status](docs/PROJECT_STATUS.md)
Expand Down
4 changes: 4 additions & 0 deletions crates/devkit-analysis/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ edition.workspace = true
license.workspace = true
authors.workspace = true
repository.workspace = true
homepage.workspace = true
documentation = "https://docs.rs/devkit-analysis"
keywords = ["stellar", "soroban", "sarif", "static-analysis"]
categories = ["development-tools"]
description = "Deterministic structural security checks and SARIF output for Soroban WASM."

[dependencies]
Expand Down
4 changes: 4 additions & 0 deletions crates/devkit-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ edition.workspace = true
license.workspace = true
authors.workspace = true
repository.workspace = true
homepage.workspace = true
documentation = "https://docs.rs/devkit-cli"
keywords = ["stellar", "soroban", "cli", "developer-tools"]
categories = ["command-line-utilities", "development-tools"]
description = "The `stellar-foundry` command-line interface."

[[bin]]
Expand Down
22 changes: 16 additions & 6 deletions crates/devkit-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ struct Cli {
#[arg(long, value_enum, default_value_t = FormatArg::Terminal, global = true)]
format: FormatArg,

/// Include the raw base64 XDR input in decoded JSON output.
#[arg(long, global = true)]
raw: bool,

#[command(subcommand)]
command: Command,
}
Expand Down Expand Up @@ -173,6 +177,9 @@ fn print_json_error(category: &str, message: &str) {

fn run(cli: Cli) -> Result<u8, CliError> {
let format: OutputFormat = cli.format.into();
let options = xdr::DecodeOptions {
include_raw: cli.raw,
};
let config_path = cli.config.clone();
match cli.command {
Command::Version => {
Expand All @@ -192,20 +199,23 @@ fn run(cli: Cli) -> Result<u8, CliError> {
}
Command::Scval { value } => {
let value = read_value(value)?;
let decoded = xdr::inspect_scval_base64(&value).map_err(runtime)?;
print_value(format, &xdr::summary("scval", &decoded));
let decoded =
xdr::inspect_scval_base64_with_options(&value, options).map_err(runtime)?;
print_value(format, &decoded);
Ok(EXIT_SUCCESS)
}
Command::Envelope { value } => {
let value = read_value(value)?;
let decoded = xdr::inspect_envelope_base64(&value).map_err(runtime)?;
print_value(format, &xdr::summary("transaction_envelope", &decoded));
let decoded =
xdr::inspect_envelope_base64_with_options(&value, options).map_err(runtime)?;
print_value(format, &decoded);
Ok(EXIT_SUCCESS)
}
Command::Event { value } => {
let value = read_value(value)?;
let decoded = xdr::inspect_event_base64(&value).map_err(runtime)?;
print_value(format, &xdr::summary("contract_event", &decoded));
let decoded =
xdr::inspect_event_base64_with_options(&value, options).map_err(runtime)?;
print_value(format, &decoded);
Ok(EXIT_SUCCESS)
}
Command::InspectWasm { path } => {
Expand Down
39 changes: 39 additions & 0 deletions crates/devkit-cli/tests/xdr_schema.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use std::process::{Command, Output};

fn run_cli(args: &[&str]) -> Output {
Command::new(env!("CARGO_BIN_EXE_stellar-foundry"))
.args(args)
.output()
.expect("run CLI")
}

#[test]
fn scval_json_output_is_versioned() {
let output = run_cli(&["--format", "json", "scval", "AAAAAwAAACo="]);
assert!(
output.status.success(),
"CLI failed: {}",
String::from_utf8_lossy(&output.stderr)
);
let value: serde_json::Value =
serde_json::from_slice(&output.stdout).expect("valid JSON output");
assert_eq!(value["schema_version"], "1.0");
assert_eq!(value["kind"], "scval");
assert_eq!(value["value"]["u32"], 42);
assert!(value.get("raw_xdr").is_none());
}

#[test]
fn raw_flag_echoes_the_base64_input() {
let output = run_cli(&["--format", "json", "--raw", "scval", "AAAAAwAAACo="]);
assert!(
output.status.success(),
"CLI failed: {}",
String::from_utf8_lossy(&output.stderr)
);
let value: serde_json::Value =
serde_json::from_slice(&output.stdout).expect("valid JSON output");
assert_eq!(value["schema_version"], "1.0");
assert_eq!(value["kind"], "scval");
assert_eq!(value["raw_xdr"], "AAAAAwAAACo=");
}
4 changes: 4 additions & 0 deletions crates/devkit-config/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ edition.workspace = true
license.workspace = true
authors.workspace = true
repository.workspace = true
homepage.workspace = true
documentation = "https://docs.rs/devkit-config"
keywords = ["stellar", "soroban", "config", "toml"]
categories = ["config", "development-tools"]
description = "Validated configuration and secret-safe diagnostics for StellarFoundry DevKit."

[dependencies]
Expand Down
4 changes: 4 additions & 0 deletions crates/devkit-contract/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ edition.workspace = true
license.workspace = true
authors.workspace = true
repository.workspace = true
homepage.workspace = true
documentation = "https://docs.rs/devkit-contract"
keywords = ["stellar", "soroban", "wasm", "contracts"]
categories = ["development-tools", "wasm", "parser-implementations"]
description = "Bounded, non-executing inspection of Soroban contract WASM artifacts."

[dependencies]
Expand Down
4 changes: 4 additions & 0 deletions crates/devkit-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ edition.workspace = true
license.workspace = true
authors.workspace = true
repository.workspace = true
homepage.workspace = true
documentation = "https://docs.rs/devkit-core"
keywords = ["stellar", "soroban", "devkit", "developer-tools"]
categories = ["development-tools"]
description = "Core types, errors, configuration, and network profiles for StellarFoundry DevKit."

[dependencies]
Expand Down
4 changes: 4 additions & 0 deletions crates/devkit-rpc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ edition.workspace = true
license.workspace = true
authors.workspace = true
repository.workspace = true
homepage.workspace = true
documentation = "https://docs.rs/devkit-rpc"
keywords = ["stellar", "soroban", "rpc", "json-rpc"]
categories = ["development-tools", "network-programming", "api-bindings"]
description = "Typed Stellar RPC protocol layer with an injectable transport for deterministic tests."

[dependencies]
Expand Down
4 changes: 4 additions & 0 deletions crates/devkit-xdr/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ edition.workspace = true
license.workspace = true
authors.workspace = true
repository.workspace = true
homepage.workspace = true
documentation = "https://docs.rs/devkit-xdr"
keywords = ["stellar", "soroban", "xdr", "scval"]
categories = ["development-tools", "encoding"]
description = "XDR, SCVal, transaction, and event inspection utilities for StellarFoundry DevKit."

[dependencies]
Expand Down
Loading
Loading