██████╗ ██████╗ █████╗ ██╗ ██╗██╗███████╗
██╔══██╗██╔══██╗██╔══██╗╚██╗██╔╝██║██╔════╝
██████╔╝██████╔╝███████║ ╚███╔╝ ██║███████╗
██╔═══╝ ██╔══██╗██╔══██║ ██╔██╗ ██║╚════██║
██║ ██║ ██║██║ ██║██╔╝ ██╗██║███████║
╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝╚══════╝
Sovereign Prediction Markets on the Canopy Network
Praxis ($PRX) is a sovereign prediction market protocol built as a Canopy Nested Chain plugin. It lets anyone create YES/NO prediction markets, stake on outcomes, and claim proportional winnings — entirely on-chain, with no platform extraction and no central authority.
Praxis runs as an application-specific blockchain with its own state, its own token, and its own transaction types. Resolution is handled by a decentralized resolver network incentivized through the Praxis Resolver Incentive System (PRIS).
Praxis is a Go plugin that runs alongside a Canopy node and communicates over a Unix socket using Protocol Buffers.
┌─────────────────────────────────────────┐
│ CANOPY NODE PROCESS │
│ ┌──────────┐ ┌────────────────────┐ │
│ │ NestBFT │ │ FSM / Controller │ │
│ │ Consensus│ │ (block lifecycle) │ │
│ └──────────┘ └────────┬───────────┘ │
└───────────────────────── ┼──────────────┘
│ Unix socket
┌────────────────▼─────────────┐
│ PRAXIS PLUGIN │
│ │
│ CheckTx() ← validate │
│ DeliverTx() ← execute │
│ EndBlock() ← epoch/PRIS │
│ │
│ 12 transaction types │
│ PRIS resolver incentives │
│ On-chain dispute resolution │
└──────────────────────────────┘
▲
│ HTTP RPC :50002 / :50003
┌────────────────┴─────────────┐
│ PRAXIS FRONTEND │
│ Single-file HTML/JS/CSS │
│ BLS12-381 signing │
│ Hand-encoded protobuf │
└──────────────────────────────┘
| Transaction | Description |
|---|---|
create_market |
Open a new YES/NO prediction market. Creator bonds 5,000 PRX. Max 5 open markets per creator. |
submit_prediction |
Stake tokens on YES or NO. One prediction per forecaster per market. |
register_resolver |
Register as a resolver by bonding PRX stake. |
propose_outcome |
Resolver proposes a winning outcome for a market at resolution height. |
commit_vote |
Panel resolver submits a blinded vote hash during dispute commit phase. |
reveal_vote |
Panel resolver reveals their vote during the reveal phase. |
tally_votes |
Finalizes a disputed market after the reveal phase. |
file_dispute |
Challenge a proposed outcome and trigger panel voting. |
finalize_market |
Settles a market after the resolution window without dispute. |
claim_winnings |
Winners claim their proportional payout from the resolved market pool. |
claim_slash |
Claim slashed stake from a resolver penalized for bad resolution. |
reclaim_stake |
Recover staked funds from markets that were never resolved. |
PRIS is the on-chain incentive layer that governs resolver behavior across epochs.
- Resolvers bond PRX stake to participate
- Each resolver has a Resolver Reputation Score (RRS) — starting at 10, floor 0
- Good resolutions earn epoch rewards from the treasury
- Bad resolutions trigger slashing and RRS penalties
- RRS gates panel eligibility: higher score = higher panel weight
- Partial unstake incurs a −10 RRS penalty; full exit resets score to 10
- 7-day unbonding period on resolver exits
Epoch rewards are distributed proportionally based on resolver stake weight at each epoch boundary via EndBlock.
| Prefix | Type | Description |
|---|---|---|
0x10 |
Market |
One record per prediction market |
0x11 |
MarketCounter |
Singleton — next market ID |
0x12 |
Prediction |
One record per (forecaster, market) pair |
0x1D |
ResolverInfo |
Resolver registration and stake |
0x1E |
ResolverCounter |
Total registered resolvers |
0x1F |
EpochSnapshot |
Snapshot of resolver stakes at epoch start |
0x20 |
ResolverReward |
Claimable reward per resolver per epoch |
0x21 |
RRSScore |
Resolver reputation score |
0x22 |
UnbondingEntry |
Pending unbond with 7-day release height |
0x23 |
DisputeRecord |
Active dispute state for a market |
0x24 |
PanelVote |
Individual panel resolver vote |
0x25 |
SlashRecord |
Slashed resolver stake available to claim |
0x26 |
TreasuryBalance |
Running treasury balance |
0x27 |
EpochRewardPool |
Total reward pool for current epoch |
0x28 |
ResolverUnbondFlag |
Tracks partial vs full unbond |
0x29 |
CreatorBondRecord |
Creator bond locked on market creation |
0x2C |
OpenMarketCount |
Per-creator open market count (spam cap) |
Winners split the entire losing pool proportionally to their contribution to the winning pool. A 2% treasury cut is taken before distribution.
Example:
YES pool: 600,000 μPRX (forecaster contributed 200,000)
NO pool: 400,000 μPRX (losing side)
Treasury: 400,000 × 2% = 8,000 μPRX
Forecaster share: 200,000 / 600,000 = 33.3%
Forecaster payout: 200,000 + (392,000 × 33.3%) ≈ 330,667 μPRX
praxis/
├── plugin/
│ ├── main.go # Entry point
│ ├── chain.json # Chain metadata (name, symbol, chainId)
│ ├── go.mod # Module: github.com/Makaveli912/praxis
│ ├── contract/
│ │ ├── contract.go # Plugin lifecycle hooks
│ │ ├── constants.go # Protocol constants and authorized wallets
│ │ ├── keys.go # State key definitions (0x10–0x2C)
│ │ ├── height.go # EndBlock epoch processor + PRIS rewards
│ │ ├── helpers.go # Shared utilities
│ │ ├── handler_*.go # One file per transaction type (12 total)
│ │ ├── lmsr.go # AMM pricing logic
│ │ └── *.pb.go # Generated protobuf structs
│ ├── crypto/
│ │ ├── bls.go # BLS12-381 key operations
│ │ └── signing.go # Sign bytes construction
│ └── proto/
│ ├── tx.proto # Transaction message definitions
│ ├── account.proto # Account and Pool types
│ └── plugin.proto # FSM communication protocol
└── ui/
├── index.html # Frontend entry point
├── app.js # BLS signing + RPC logic
└── style.css # Styles
- Go 1.24+
- A running Canopy node
protoc+protoc-gen-go(only needed to regenerate proto files)
git clone https://github.com/canopy-network/canopy.git
cd canopy
go build -o ~/go/bin/canopy ./cmd/main
canopy startgit clone https://github.com/Makaveli912/praxis.git
cd praxis/plugin
go build -buildvcs=false -o go-plugin .
cp go-plugin /tmp/plugin/go-plugin# In a dedicated terminal — never start the plugin manually before the node
canopy startWatch for:
Plugin go started: go-plugin started successfully
Plugin service listening on socket: /tmp/plugin/plugin.sock
python3 -m http.server 8080 --directory uiOpen http://localhost:8080. Go to Node → set host to localhost → Apply. Green dot confirms connection.
Go to Signer → paste your BLS12-381 private key → Load Key. Your address will be auto-derived and filled into all transaction forms.
| Property | Value |
|---|---|
| Name | Praxis |
| Symbol | $PRX |
| Denomination | μPRX (micro-PRX) |
| Chain ID | 1 |
| Network ID | 1 |
| Constant | Value |
|---|---|
| Creator bond | 5,000 PRX |
| Max open markets per creator | 5 |
| Treasury fee | 2% of losing pool |
| Resolver unbonding period | 7 days |
| Initial RRS | 10 |
| RRS floor | 0 |
| Partial unstake RRS penalty | −10 |
| Full exit RRS reset | 10 |
MIT — see LICENSE