Staking (RUJI, bRUNE, TCY)
Technical documentation for wallets, portfolio apps, staking dashboards, and user-facing apps integrating staking markets powered by the Rujira staking contract.
This guide is scoped to user-owned staking positions. It does not cover protocol/operator revenue setup, revenue converter administration, or contract sudo messages.
Overview
The Rujira staking contract is generic. A deployed staking market can be configured for RUJI, bRUNE, TCY, or another supported bond token. Each market has its own contract address and config.
A staking market supports two user paths:
Account staking
The market's bond_denom
Account staking position (non-transferable)
Rewards accrue as revenue_denom and are claimed manually.
Liquid staking
The market's bond_denom
Liquid staking receipt tokens (transferable)
Rewards are converted into more bond_denom, increasing the value of each receipt token.
Always query the staking contract config before building transactions. The contract tells you which token to stake through bond_denom and which reward token account stakers can claim through revenue_denom.
Existing Staking Markets
Use this table as an integration hint, not as the source of truth. The live contract config should still be queried before every staking flow.
RUJI staking
x/ruji
RUJI
x/staking-x/ruji
sRUJI
bRUNE staking
x/brune
bRUNE
x/staking-x/brune
ybRUNE
TCY staking
tcy
TCY
x/staking-tcy
sTCY
The bank metadata for x/ruji, x/brune, and the liquid receipt denoms uses 8 display decimals. The tcy supply exists on chain, but the bank metadata endpoint may not return a base metadata object for tcy; clients should use the chain/app asset registry or a maintained token list as a display fallback.
Who This Guide Is For
Wallets
Show RUJI balance, account stake, pending revenue, liquid receipt balance, and sign bond/claim/withdraw/unbond transactions.
Portfolio apps
Display account positions, pending rewards, liquid share positions, and pool status.
Staking UIs
Provide standard staking and auto-compounding staking flows.
Card or repayment apps
Let users claim staking revenue and then use the claimed funds in the app's own repayment flow.
Prerequisites
The user needs a THOR/Rujira app-layer address.
The user needs the staking
bond_denom; for RUJI staking this isx/ruji.Account staking rewards are paid in
revenue_denom, which should be read from contract config.Liquid staking receipt token denom is derived from the bond denom:
x/staking-<bond_denom>.All
Uint128amounts are strings in JSON.
Useful references:
RUJI token FAQ
Rujira secured assets
RUJI bank metadata
Deployment list
Architecture
Do not call settle directly. It is an internal self-call used by the staking contract after revenue conversion.
Contract Address and Config
The current staking contract addresses should be read from official deployment data. If static addresses are needed in a downstream guide, verify them first against the Rujira deployment page and look for the relevant rujira-staking instances.
Model staking markets by contract address:
Query config before rendering the staking UI:
Example response shape:
bond_denom
Token users bond into this staking market. Examples: x/ruji, x/brune, tcy.
revenue_denom
Token account stakers claim as rewards.
revenue_converter
Converter used internally to compound liquid staking rewards. Wallet UIs should display or ignore this, not execute it.
fee
Optional protocol fee on distributable revenue, shaped as [percentage, recipient].
Do not hardcode the reward token from product copy. Different staking markets can pay different revenue_denom assets, and the live config is the source of truth for transaction builders.
Staking Concepts
Account Staking vs. Liquid Staking
Account staking and liquid staking use the same bond token, but they behave differently.
Execute namespace
account
liquid
User sends
bond_denom
bond_denom
User receives
Stored account position
Receipt token balance
Rewards
Claimed manually as revenue_denom
Converted into more bond_denom in the pool
Exit
account.withdraw
liquid.unbond with receipt token funds
Liquid Receipt Denom
The liquid receipt denom is:
Examples:
x/ruji
x/staking-x/ruji
x/brune
x/staking-x/brune
tcy
x/staking-tcy
Derive this from config in code:
Do not assume the receipt denom from the display symbol. Use the bank denom.
Revenue Distribution Timing
Revenue distribution is lazy. Sending revenue_denom to the staking contract does not immediately update every account. The contract distributes pending revenue at the start of the next account or liquid staking execute.
For UI, this means:
statusshows the current stored state plus raw undistributed revenue.account.pending_revenuecan change after any staking action triggers distribution.Re-query
status,account, and bank balances after every staking transaction.
Query Integration
Query Status
Response shape:
account_bond
Total bond_denom bonded in account staking.
assigned_revenue
Total revenue_denom already assigned to account stakers but not yet claimed.
liquid_bond_shares
Total liquid receipt shares issued.
liquid_bond_size
Total bond_denom backing the liquid staking pool.
undistributed_revenue
revenue_denom currently in the contract but not yet distributed.
For liquid staking display, the simple pool ratio is:
If liquid_bond_shares is zero, show the ratio as zero or unavailable.
Query Account
Response shape:
account only works for addresses that have an account staking record. If the query returns not found, show a zero account position:
There is no account-list query and no pagination in the staking contract.
Account Staking Integration
Account staking is the standard staking path where the user bonds the market token and manually claims rewards.
Bond
Funds:
Use config.bond_denom for the funds denom. Send only the bond denom.
If the account already has pending rewards, bond claims those rewards first and sends them to the user before increasing the bonded amount.
Claim
Claim is nonpayable. Send no funds.
If there are claimable rewards, the contract sends revenue_denom to the user. If the user already has an account staking record and rewards are zero, the transaction can still complete and emit a zero-amount claim event. If the user has never bonded, do not offer claim; there is no account record yet.
Withdraw
Partial withdraw:
Full withdraw:
Withdraw is nonpayable. Send no funds.
Withdraw requires an existing account staking record. It always claims pending rewards first. The payout can include both bond_denom and revenue_denom.
TypeScript Example: Account Bond
TypeScript Example: Claim and Use Rewards
This is the wallet/user flow a card or repayment app should use. The staking contract claims rewards to the user first; the app then uses the user's resulting revenue_denom balance in its own repayment flow.
Liquid Staking Integration
Liquid staking is the auto-compounding path. The user bonds the market token and receives receipt tokens. As revenue is converted into more bond_denom, the pool size grows and each receipt token represents more underlying bond token.
Bond
Funds:
The contract mints receipt tokens to the user. Derive the receipt denom from config:
Unbond
Funds:
Liquid unbond burns receipt tokens and returns the user's proportional bond_denom. The returned amount depends on the current pool ratio and is floor-rounded by share-pool math.
TypeScript Example: Liquid Bond and Unbond
Events
CosmWasm event types usually appear in indexed transaction logs with a wasm- prefix.
Account staking events:
account.bond
owner, amount
account.claim
owner, amount
account.withdraw
owner, amount, rewards
Liquid staking events:
liquid.bond
owner, amount, shares
liquid.unbond
owner, shares, returned
Internal settlement event:
settle has a returned attribute and is emitted by the contract's internal revenue-conversion flow. User interfaces can index it, but users should not build or sign settle messages.
Use events for fast UI updates, but re-query contract state and bank balances after the transaction is indexed.
UI and UX Checklist
Show account staking and liquid staking as separate modes.
Query
configfirst and use itsbond_denomandrevenue_denom.Display the bond token from bank metadata or a maintained token registry. Do not hardcode a single staking denom.
For TCY, handle metadata fallback because
tcymay not return a base bank metadata object even though the denom exists on chain.For account staking, show
bondedandpending_revenue.For account staking, explain that rewards are claimable manually in
revenue_denom.For liquid staking, show receipt token balance and estimated underlying
bond_denom.For liquid staking, explain that rewards compound by increasing pool value, not by sending revenue directly to the user.
For card or repayment apps, claim rewards first, then use the user's claimed balance in the app repayment flow.
Prevent users from attaching funds to
claimorwithdraw.Prevent users from sending
config.bond_denomtoliquid.unbond; it requires the receipt token.Refresh
status,account, and bank balances after every transaction.
Common Errors and Gotchas
Wrong funds denom on bond
Account and liquid bond require bond_denom.
Query config and send only config.bond_denom.
Claim sent with funds
account.claim is nonpayable.
Send no funds.
Withdraw sent with funds
account.withdraw is nonpayable.
Send no funds.
Liquid unbond sends the bond token
liquid.unbond burns receipt tokens, not bond tokens.
Send x/staking-<bond_denom> funds.
Account query fails for a new user
The account record does not exist until the user bonds.
Treat not found as zero bonded and zero pending revenue.
Claim or withdraw fails for a new user
There is no account staking record yet.
Disable claim and withdraw until the user has an account position.
Pending rewards look stale
Distribution runs lazily during staking executes.
Re-query after transactions and explain update timing.
User expects liquid rewards as the account reward token
Liquid rewards are converted into more bond token value.
Show pool ratio and receipt-token underlying value.
Tiny liquid bond mints zero shares
Share math floors issuance.
Block very small deposits or explain the failure.
Unbond amount exceeds receipt balance
Share pool rejects over-unbonding.
Check the user's receipt token balance before signing.
Message Reference
Queries
Executes
Do not use this internal message in wallet or user integrations:
Last updated
