Pulsar Stellar is a developer toolkit for Soroban contract events. Every Stellar project that needs to consume its contract's events today writes the same plumbing from scratch: XDR decoders, indexer glue, custom APIs. Pulsar Stellar provides three shared building blocks so they don't have to. A Rust library that turns raw contract events into typed data, a Go daemon that stores historical events past the seven-day RPC retention window, and a web explorer where anyone can paste a contract ID and browse every event that contract has ever emitted, decoded and searchable. It serves Soroban dapp builders, backend engineers integrating with existing protocols, and auditors reviewing contract behavior post-deployment.
The toolkit is three repositories. A contract emits events; pulsar-core (this
repo) provides the reference contract and the Rust decoder; pulsar-app indexes,
serves, and displays those events; pulsar-docs documents the whole.
flowchart LR
subgraph core["pulsar-core (this repository)"]
SC["pulsar-showcase<br/>reference contract"]
DEC["pulsar-decoder<br/>typed decoder crate"]
end
SC -->|emits events| RPC["Soroban RPC"]
SC -.->|events are the test fixture| DEC
RPC -->|poll, decode, store, serve| APP["pulsar-app<br/>SDK, indexer, explorer"]
DEC -.->|typed decoding, v0.2 onward| APP
APP --> USER["dapp builders, backends, auditors"]
pulsar-showcase is the anchor the rest of the toolkit is calibrated against:
every function it exposes exists to emit a specific event shape, so its events
are both the decoder's test fixtures and the demo the SDK and explorer are built
to read. pulsar-decoder is the canonical Rust and browser decoder for that data,
a placeholder until v0.2.0-contracts.
pulsar-core is the Rust contract layer. It carries two artifacts that co-evolve:
pulsar-showcase: the reference Soroban contract. Every function on it exists to exercise a specific decoder capability, which makes its emitted events the test fixture and documentation demo for the rest of the toolkit.pulsar-decoder: the crate that turns raw contract events into typed data, published to crates.io from v0.2.0-contracts onward.
The sibling repository pulsar-stellar/pulsar-app carries the TypeScript SDK, the Go indexer, and the web explorer. Documentation is maintained in the separate pulsar-stellar/pulsar-docs repository and publishes through GitBook.
Sprint 1. The contract is complete and its full public surface is implemented and tested.
| Artifact | State |
|---|---|
pulsar-showcase contract |
complete, 8 public functions, 6 event types |
| Test suite | 54 tests, 98.7 percent line coverage |
pulsar-decoder crate |
placeholder, real content at v0.2.0-contracts |
| Testnet deployment | live, see Deployment below |
| Published crate | not published |
The first release is v0.1.0-contracts, which ships the showcase contract
deployed to Stellar testnet with its contract ID recorded in the tag body.
The full roadmap lives in docs/roadmap-core.md. This
repository ships two artifacts that version independently but align to
product-level milestones. Releases are tagged v{MAJOR}.{MINOR}.{PATCH}-contracts.
| Release | Scope | State |
|---|---|---|
v0.1.0-contracts |
pulsar-showcase reference contract on testnet |
done, deployed and initialized |
v0.2.0-contracts |
pulsar-decoder crate first release, published to crates.io |
planned |
v0.3.0-contracts |
SEP-41 token showcase contract | planned |
v0.4.0-contracts |
wasm bindings for browser-side decoding | planned |
v0.5.0-contracts |
pulsar-events derive macros for contract authors |
planned |
v1.0.0-contracts |
audit-ready, mainnet-committed, semver-stable API | planned |
Each milestone past v0.1 is deferred by choice with an explicit trigger recorded
in the roadmap, not dropped. The decoder crate does not block the app layer: the
pulsar-app indexer carries its own Go decoder until the wasm path lands.
- Release tag:
v0.1.0-contracts - Application layer:
pulsar-stellar/pulsar-app - Decision log (ADRs):
.agent/decisions.md
The pulsar-decoder crate is not on crates.io yet; it is published from
v0.2.0-contracts onward.
Rust installs itself from rust-toolchain.toml on the first cargo command.
stellar-cli is a host tool and installs on the stable channel, from outside this
directory, because the project pin is older than stellar-cli needs to build:
cd ~ && rustup run stable cargo install --locked --force stellar-cliFull toolchain list in docs/requirements.md section 1.8. Reasoning for the two
channels in ADR-007.
scripts/build.shWraps stellar contract build, checks the artifact exists, and reports its size.
Plain cargo build compiles the crate but does not produce a deployable
artifact.
Needs a funded identity:
stellar keys generate deployer --network testnet
stellar keys fund deployer --network testnet
scripts/deploy-testnet.shThe script checks the artifact and identity before submitting anything, and prints the contract ID on success.
A freshly deployed contract has no admin, and every state-changing function
returns NotInitialized until one is set. This call is required before the
contract does anything:
stellar contract invoke \
--id <CONTRACT_ID> \
--source deployer \
--network testnet \
-- initialize --admin <ADMIN_ADDRESS>
Calling it twice returns `Error(Contract, #1)`, which is `AlreadyInitialized`.The admin address authorizes set_admin and emit_custom. Rotation requires the
current admin's signature, so a lost admin key cannot be recovered.
stellar contract invoke --id <CONTRACT_ID> --source deployer --network testnet \
-- adminReturns the admin address. The contract's event history is browsable at
https://stellar.expert/explorer/testnet/contract/<CONTRACT_ID>.
Live on Stellar testnet and initialized.
| Contract ID | CDNWTVUDKCCGW7GOC6SBLUFXXUCD2YDHWRDUSXZ6CYBQKQWLCUYYWI5L |
| Admin | GCQURZFYPPAN76FRARROTSTYVH2LQ5AP7OLDXMJPIQ7STDOM55FXWD4T |
| Wasm hash | e8fd07e940e92d9c6a56b22573337f1cacee956a3b507990db4efa2522306dcf |
| Network | testnet |
Browse its event history at stellar.expert.
Read it without installing anything:
stellar contract invoke --id CDNWTVUDKCCGW7GOC6SBLUFXXUCD2YDHWRDUSXZ6CYBQKQWLCUYYWI5L \
--source <YOUR_IDENTITY> --network testnet -- adminThe admin is the deploying identity. For a reference contract whose purpose is emitting event shapes rather than holding value, separating the two would add a key to manage without adding a guarantee.
Testnet is reset periodically, so this contract will eventually be archived and
the ID will stop resolving. When that happens, redeploy with scripts/build.sh
and scripts/deploy-testnet.sh and update this section.
| Tool | Version |
|---|---|
| Rust, project toolchain | 1.92.0, pinned in rust-toolchain.toml |
| Rust, host toolchain | stable 1.93 or newer, for installing binary tools only |
| Build target | wasm32v1-none |
| soroban-sdk | 26.1.0, pinned exactly |
| stellar-cli | 27.1.0 or newer |
The contract is built with stellar contract build, never with plain cargo build.
This project's initial scaffolding and much of its ongoing implementation is written with Claude Code assistance under human review. Every commit is authored, reviewed, and merged by a human maintainer. Design decisions, architecture choices, and merge judgments are human. If you contribute a PR, we don't require you to disclose whether AI tools helped you write it; we do require that your code passes review, tests, and the discipline rules in the requirements document.
Apache-2.0.