This guide covers XPR staking, Block Producer voting, the DPoS consensus mechanism, and XPR Network's unique resource model.
XPR Network uses Delegated Proof of Stake (DPoS) where token holders stake XPR and vote for Block Producers who validate transactions and produce blocks.
Key differences from other EOSIO chains:
- Zero gas fees for regular users
- Subscription-based resources for dApps (not stake-based CPU/NET)
- 4 Block Producer minimum voting requirement
- 24-hour unstaking delay for security
- Governance participation - Vote for Block Producers
- Earn rewards - Staking rewards distributed proportionally
- Security - 24-hour unstaking delay protects against key compromise
- Go to https://explorer.xprnetwork.org
- Login with WebAuth wallet
- Select Wallet → Short Stake XPR
- Go to Stake tab
- Enter amount (or use 25/50/75/100% buttons)
- Click Stake and sign transaction
# Stake XPR
proton action eosio stakexpr '{"from":"myaccount","receiver":"myaccount","stake_xpr_quantity":"1000.0000 XPR"}' myaccountasync function stakeXPR(session: any, amount: string): Promise<any> {
return session.transact({
actions: [{
account: 'eosio',
name: 'stakexpr',
authorization: [session.auth],
data: {
from: session.auth.actor.toString(),
receiver: session.auth.actor.toString(),
stake_xpr_quantity: amount // e.g., "1000.0000 XPR"
}
}]
}, { broadcast: true });
}Unstaking takes 24 hours to complete. This is a security feature:
- If your keys are compromised, you have 24 hours to use your owner key to change your active key before funds can be withdrawn
- The attacker cannot speed up the unstaking process
- Select Wallet → Short Stake XPR
- Go to Unstake tab
- Enter amount to unstake
- Click Unstake and sign
- Wait 24 hours
- Go to Refund tab to claim (or it processes automatically)
# Start unstaking
proton action eosio unstakexpr '{"from":"myaccount","receiver":"myaccount","unstake_xpr_quantity":"500.0000 XPR"}' myaccount
# After 24 hours, claim refund (usually automatic)
proton action eosio refundxpr '{"owner":"myaccount"}' myaccountasync function unstakeXPR(session: any, amount: string): Promise<any> {
return session.transact({
actions: [{
account: 'eosio',
name: 'unstakexpr',
authorization: [session.auth],
data: {
from: session.auth.actor.toString(),
receiver: session.auth.actor.toString(),
unstake_xpr_quantity: amount
}
}]
}, { broadcast: true });
}
// After 24 hours
async function claimRefund(session: any): Promise<any> {
return session.transact({
actions: [{
account: 'eosio',
name: 'refundxpr',
authorization: [session.auth],
data: {
owner: session.auth.actor
}
}]
}, { broadcast: true });
}Block Producers (BPs) are the backbone of XPR Network:
- Validate transactions and produce blocks
- Elected via Delegated Proof of Stake (DPoS)
- Only top 21 BPs actively produce blocks
- Must operate reliable, secure infrastructure
- Must have XPR staked before voting
- Vote for 4 Block Producers (
max_bp_per_vote= 4). Fewer is accepted by the chain but setsisqualified = false, so you earn no staking rewards - Voting choice does NOT affect staking reward amount
Choose BPs who:
- Run solid, reliable infrastructure
- Contribute to ecosystem development
- Support developers and dApps
- Drive adoption and marketing
- Stake XPR first (if not already staked)
- Select Vote from top menu
- View Block Producer list (ranked by votes)
- Check boxes for up to 4 BPs
- Click blue VOTE button
- Sign transaction
# Vote for block producers (exactly 4 — fewer or more forfeits staking rewards)
proton action eosio voteproducer '{"voter":"myaccount","proxy":"","producers":["bp1","bp2","bp3","bp4"]}' myaccountasync function voteForProducers(
session: any,
producers: string[] // exactly 4 to qualify for rewards (max 4)
): Promise<any> {
if (producers.length !== 4) {
throw new Error('Vote for exactly 4 Block Producers to qualify for staking rewards');
}
// Producers must be sorted alphabetically
const sortedProducers = [...producers].sort();
return session.transact({
actions: [{
account: 'eosio',
name: 'voteproducer',
authorization: [session.auth],
data: {
voter: session.auth.actor,
proxy: '',
producers: sortedProducers
}
}]
}, { broadcast: true });
}async function getBlockProducers(): Promise<any[]> {
const { rows } = await rpc.get_table_rows({
code: 'eosio',
scope: 'eosio',
table: 'producers',
limit: 100
});
// Sort by total votes
return rows.sort((a, b) => parseFloat(b.total_votes) - parseFloat(a.total_votes));
}
// Get top 21 (active producers)
const producers = await getBlockProducers();
const activeProducers = producers.slice(0, 21);- Rewards are distributed automatically and proportionally based on staked amount
- Can claim once every 24 hours
- Voting choice does NOT affect reward amount
- Select Wallet → Short Stake XPR
- Go to Claim Rewards tab
- Click Claim button
- Sign transaction
# voterclaim = staker/voter rewards. (eosio::claimrewards is the BLOCK PRODUCER pay claim.)
proton action eosio voterclaim '{"owner":"myaccount"}' myaccount
# Claim and re-stake in one step
proton action eosio voterclaimst '{"owner":"myaccount"}' myaccountasync function claimStakingRewards(session: any): Promise<any> {
return session.transact({
actions: [{
account: 'eosio',
name: 'voterclaim', // staker rewards; 'claimrewards' is the BP pay claim
authorization: [session.auth],
data: {
owner: session.auth.actor
}
}]
}, { broadcast: true });
}XPR Network has a fundamentally different resource model than other EOSIO chains:
| Feature | XPR Network | EOS / WAX |
|---|---|---|
| User Fees | Zero for regular users | Users pay CPU/NET |
| CPU/NET Model | Subscription-based for dApps | Stake-based |
| RAM | Purchase with XPR | Purchase with tokens |
| Target Users | Consumer apps | General blockchain |
Regular users on XPR Network get free resources for transactions. This is why XPR is marketed as "gas-free" - end users don't pay transaction fees.
dApps and developers can purchase monthly resource subscription plans at https://resources.xprnetwork.org:
| Plan | Price | CPU Credits | NET Credits | Transactions/Day | Best For |
|---|---|---|---|---|---|
| Basic | 100 XPR/mo | 100 | 10 | ~500 | Small demo apps |
| Plus | 1,000 XPR/mo | 1,000 | 100 | ~5,000 | Games, small apps |
| Pro | 10,000 XPR/mo | 10,000 | 1,000 | ~50,000 | Most apps + Priority Support |
| Enterprise | 100,000 XPR/mo | 100,000 | 10,000 | ~500,000 | Priority Support + Surge availability |
Key Details:
- CPU is the scarcer resource - System allocates at 80:20 CPU:NET ratio
- Upgrade/downgrade anytime - Remaining time credited toward new plan
- Battle tested - Enterprise BOT runs 1M+ transactions daily with steady consumption
The resources contract manages subscription plans:
// Query available plans
async function getResourcePlans(): Promise<any[]> {
const { rows } = await rpc.get_table_rows({
code: 'resources',
scope: 'resources',
table: 'plans',
limit: 100
});
return rows;
}
// Query account subscription
async function getSubscription(account: string): Promise<any | null> {
const { rows } = await rpc.get_table_rows({
code: 'resources',
scope: 'resources',
table: 'subscription',
lower_bound: account,
upper_bound: account,
limit: 1
});
return rows[0] ?? null;
}async function buyResourcePlan(
session: any,
planIndex: number,
quantity: number = 1
): Promise<any> {
return session.transact({
actions: [{
account: 'resources',
name: 'buyplan',
authorization: [session.auth],
data: {
account: session.auth.actor,
plan_index: planIndex,
plan_quantity: quantity
}
}]
}, { broadcast: true });
}Deposit first, then
buyplan.buyplanpays from the account's deposit in theresourcescontract, not from its token balance. Transfer the plan price (from theplanstable) toresourcesfirst. The deposit is credited to the sender (resources::accounts, scoperesources, one row per account with abalancesmap). Then callbuyplan:proton action eosio.token transfer '{"from":"myaccount","to":"resources","quantity":"100.0000 XPR","memo":""}' myaccount proton action resources buyplan '{"account":"myaccount","plan_index":0,"plan_quantity":1}' myaccountVerified on mainnet (September 2026) as two separate transactions: the deposit, then
buyplanfor plan 0 (Basic, 744 h).buyplanemits aplanreceipt, and thesubscriptionrow (scoperesources) shows the plan andstart_time. The deposit andbuyplanprobably also work as two actions in one transaction, but that wasn't tested.When you need it: a bulk job from one account (a large NFT mint, an airdrop) can use up the free NET allowance in a few hours. Nodes then reject transactions with
transaction net usage is too high: X > Y. Basic gives about 10x the free NET, and it was enough for a 3,333-asset mint (167 transactions of ~5.6 KB).
RAM is used to store data on-chain (table rows, NFTs, tokens, etc.). Unlike CPU/NET:
- RAM must be purchased (not subscription-based)
- RAM is a persistent resource (data stays until deleted)
- RAM can be sold back when no longer needed
| Item | Cost |
|---|---|
| RAM Storage | Dynamic (Bancor algorithm), ~0.0004 XPR per byte (≈0.41 XPR/KB, Sept 2026 — read eosio::rammarket for the live price) |
| Free RAM (WebAuth) | 12,000 unsellable bytes per account |
| Maximum Purchase | 6 MB |
Portal: https://resources.xprnetwork.org/storage
- NFT storage
- Marketplace sales data
- Token balances
- On-chain application data
# Buy RAM in bytes
proton ram:buy myaccount myaccount 50000
# Or via action
proton action eosio buyrambytes '{"payer":"myaccount","receiver":"myaccount","bytes":50000}' myaccountasync function buyRAM(
session: any,
bytes: number,
receiver?: string
): Promise<any> {
return session.transact({
actions: [{
account: 'eosio',
name: 'buyrambytes',
authorization: [session.auth],
data: {
payer: session.auth.actor,
receiver: receiver ?? session.auth.actor,
bytes: bytes
}
}]
}, { broadcast: true });
}async function sellRAM(session: any, bytes: number): Promise<any> {
return session.transact({
actions: [{
account: 'eosio',
name: 'sellram',
authorization: [session.auth],
data: {
account: session.auth.actor,
bytes: bytes
}
}]
}, { broadcast: true });
}# Via CLI
proton account myaccount
# Shows RAM quota and usage// Via RPC
async function getRAMUsage(account: string): Promise<{
used: number;
quota: number;
available: number;
}> {
const accountInfo = await rpc.get_account(account);
return {
used: accountInfo.ram_usage,
quota: accountInfo.ram_quota,
available: accountInfo.ram_quota - accountInfo.ram_usage
};
}XPR Network has a governance portal for proposals and voting:
URL: https://gov.xprnetwork.org
Features:
- Submit governance proposals
- Vote on active proposals
- View proposal history
- Track governance metrics
| Wallet | Type | Platforms | Best For |
|---|---|---|---|
| WebAuth | Mobile/Web | iOS, Android, Web | General users (recommended) |
| Anchor | Mobile/Desktop | iOS, Android, Mac, Win, Linux | Advanced users, owner key access |
| Ledger | Hardware | Nano X, Nano S | Maximum security |
| TokenPocket | Mobile | iOS (TestFlight), Android | Multi-chain users |
| Scatter | Desktop | Mac, Windows, Linux | Desktop multi-chain |
# Stake XPR
proton action eosio stakexpr '{"from":"ACCOUNT","receiver":"ACCOUNT","stake_xpr_quantity":"1000.0000 XPR"}' ACCOUNT
# Unstake XPR
proton action eosio unstakexpr '{"from":"ACCOUNT","receiver":"ACCOUNT","unstake_xpr_quantity":"500.0000 XPR"}' ACCOUNT
# Claim refund (after 24h)
proton action eosio refundxpr '{"owner":"ACCOUNT"}' ACCOUNT
# Claim staking rewards (voterclaimst to auto-restake)
proton action eosio voterclaim '{"owner":"ACCOUNT"}' ACCOUNT
# Vote for BPs (exactly 4 to qualify for rewards)
proton action eosio voteproducer '{"voter":"ACCOUNT","proxy":"","producers":["bp1","bp2","bp3","bp4"]}' ACCOUNT| Contract | Table | Description |
|---|---|---|
eosio |
producers |
Block Producer list |
eosio |
voters |
Voter information |
eosio |
global |
Chain parameters |
eosio.proton |
usersinfo |
User profiles |
resources |
plans |
Resource subscription plans |
resources |
subscription |
Active subscriptions |
| Resource | URL |
|---|---|
| Explorer (Mainnet) | https://explorer.xprnetwork.org |
| Explorer (Testnet) | https://testnet.explorer.xprnetwork.org |
| Governance Portal | https://gov.xprnetwork.org |
| Resources Portal | https://resources.xprnetwork.org |
| WebAuth Wallet | https://webauth.com |
| Help Desk | https://help.xprnetwork.org |