Miden publishing is part of the stable
pragma-sdk release behind the [miden] extra. The Miden testnet runs node 0.17 since October 2026: use pragma-sdk >= 2.16.3 (pm-publisher >= 0.1.0a13), older releases are rejected by the node.pragma-sdk, adding Miden support requires minimal changes — the same pipeline pushes to both networks automatically.
Step 1 — Install
[miden] extra pulls in pm-publisher, the Rust-backed Python wheel that drives the Miden client. No Rust toolchain required.
Step 2 — Initialize your publisher account
Run this once. It creates your publisher account on Miden and writes your credentials locally. Pass the Pragma oracle id (see the pragma-miden README): it is stored next to your publisher id.Step 3 — Fund your account
Miden 0.17 charges every transaction a fee in the chain’s native asset, paid from your account’s vault: about 112 base units per 14-entry batch, 119 for the registration, nothing for reads. On testnet the only source is the public faucet. Your account is created withBasicWallet, so it can receive the faucet’s note:
maintain_fee_balance() reads the balance (fee_balance()) at most every 2 minutes and, below FEE_REFILL_THRESHOLD (100 000 base units, ~45 minutes of publishing at one batch every 3 s), solves the faucet’s proof-of-work, mints a note and consumes it. It never raises: failures are logged and counted.
The 0.17 faucet gives at most 10 000 base units (0.01 token) per request, one request per account every 30 seconds, and is sometimes unavailable. One refill therefore covers only ~90 batches (about 9 minutes at one batch every 6 s): refills are frequent, and a faucet outage eventually starves the account, so monitor fee_balance(). After a failed refill the publisher retries 10 minutes later if the account can still pay for batches, and at the next 2-minute check if it is nearly empty. The same is available from the CLI: pm-publisher-cli -n testnet fund / balance.
Step 4 — Get registered
Share your publisher ID (frompragma_miden.json) with the Pragma team. We will register it on the oracle so your prices are included in the median computation.
Step 5 — Publish prices
Once registered, publish entries as part of your existing data pipeline:publish_entries submits a single batched Miden transaction containing all entries, regardless of how many pairs you push. A failure aborts the batch (atomic), but the next tick retries naturally.
When converting from a pragma-sdk Starknet Entry, use MidenEntry.from_starknet_entry(entry) — it resolves decimals from the pair’s currencies (min(base.decimals, quote.decimals)), so you never have to hardcode them.
Starknet + Miden together (price-pusher)
If you run the price-pusher, Miden publishing is enabled with one extra flag. It runs as its own loop, decoupled from the Starknet push cadence: every --miden-publish-interval seconds (default 3) the latest polled prices are published to Miden in one batched transaction, whether or not Starknet pushed anything. Miden calls are offloaded to a thread with per-call timeouts, so a hung or slow Miden node never affects Starknet, and a Starknet outage (out of gas, RPC down) never stops the Miden feed.
--miden-network accepts testnet, devnet or local. --miden-oracle-id overrides the oracle read from pragma_miden.json. The three path flags are optional and default to the working directory. If Miden initialization fails at startup, Miden publishing is disabled with an error log and the Starknet pusher keeps running.
The pusher dedupes entries by pair using the median of source prices before forwarding to Miden, so a tick with BTC/USD × 5 sources produces a single BTC/USD entry on Miden. Only pairs present in STARKNET_PAIR_TO_MIDEN_FAUCET are forwarded; the rest are silently skipped.
The pusher also keeps the account funded: after each Miden tick it calls maintain_fee_balance() and exposes pragma_miden_fee_balance{account} and pragma_miden_refills_total{account,result} on /metrics, so you can alert on a low balance or a failed refill.
Available pairs
The pusher resolves decimals dynamically from each pair’s currencies (
min(base.decimals, quote.decimals)); you don’t have to hardcode them. To add a pair, extend STARKNET_PAIR_TO_MIDEN_FAUCET in pragma_sdk/miden/client.py and make sure both currencies are in supported_assets.yaml.
To publish a pair on Miden without pushing it to Starknet, put it in a price-pusher config group flagged miden_only: true: the group is polled by the fetchers and forwarded to Miden, but no Starknet listener is created for it. This is how 6:0 to 14:0 are published: