
Near NFT Staking
A Telegram Mini App (@NearNFTStaking_bot) for staking NFTs and earning $NEAR rewards — fully on-chain, live on NEAR mainnet.

What is Near NFT Staking?Mainnet
NFT Legion Staking — Project Overview
NFT staking and marketplace for the NEAR Legion collection, delivered as a Telegram Mini App. Live on NEAR mainnet.
| Component | Account |
|---|---|
| Staking contract | legion-staking.near |
| Marketplace contract | legion-marketplace.near |
| NFT collection | nearlegion.nfts.tg (NEP-171) |
Tech Stack
Smart contracts — Rust, near-sdk 5.1, deployed on NEAR mainnet. Two independent crates, each built with overflow-checks = true and panic = "abort".
Telegram Mini App — React 18 + Vite. Wallet connection via @hot-labs/near-connect (HOT Wallet, MyNearWallet, Meteor). Blockchain interaction directly through NEAR RPC (fastnear.com).
Telegram bot — TypeScript, Telegraf.js. SQLite through sql.js with persistent-disk storage.
Backend — Node.js + Express, TypeScript. Telegram webhook, REST API for the Mini App, cron jobs.
NEAR integration — near-api-js for RPC reads, near-kit for NEP-413 signature verification.
Hosting — Render (paid instance, always-on, persistent disk). Auto-deploy from main.
Completed
Staking contract
- NFT staking via
nft_transfer_call(NEP-171) - Staking periods: 7 / 14 / 30 days
- Tiered APR: rate grows with the number of NFTs staked by an account
- Rewards reserved from the pool at stake creation — payouts are always covered
- NFT locked until the period ends, enforced by
require! - Callbacks on every transfer and payout, with state rollback on failure
- Batch staking, up to 4 NFTs per transaction
- Leaderboard with deterministic ordering
- Stats methods:
get_contract_stats,get_leaderboard,get_my_rank, and others - Human-readable errors instead of raw traps
- Structured logs for every event
- Paginated cleanup of claimed records (
prune_claimed_stakes) - Emergency NFT recovery for abandoned stakes (
admin_return_nft)
Marketplace contract
- Escrow listings via
nft_transfer_call, price passed inmsg - Cart purchase: up to 4 NFTs in a single transaction and a single signature
- 0.5% marketplace fee
- Full refund to the buyer if an NFT transfer fails, with the listing returned to sale
- Seller payout under callback
- Duplicate cart entries rejected at contract level
- Listing price bounded to prevent unbuyable junk listings
- Seller-only cancellation, requiring 1 yoctoNEAR
- Emergency listing recovery (
admin_return_listing)
Telegram bot
- NEAR wallet verification through message signing (NEP-413)
- NFT ownership check against the NEAR Legion collection
- Private channel invite after successful verification
- Cron NFT check for channel members, twice daily
- Removal from the channel if the NFT is sold and no active stakes remain
- Protection against false removal on RPC errors
- Notifications: matured stakes and NFT sales, the latter verified on-chain
- Bilingual RU / EN
- Rate limiting on API endpoints
- Telegram
initDatavalidation by signature /api/statusand/api/stakesprotected by API key
Telegram Mini App
- NFT display from the connected wallet
- Staking flow: NFT and period selection, reward preview before signing
- Progress bar and remaining time for each active stake
- Unstake available only after the period completes
- Marketplace: listings grid, sell dialog, cart, purchase
- Leaderboard and personal rank
- 6 colour palettes × light/dark theme
- iOS viewport handling for Telegram's embedded webview
- Bilingual RU / EN with auto-detection from Telegram
Security
- Internal security review of both contracts. 15 findings across access control, escrow integrity, callback handling, gas budgeting and state growth; 14 are fixed and redeployed to mainnet, the remaining one requires a state migration and is scheduled.
- Most significant fix: stake ownership was derived from
sender_idrather thanprevious_owner_id. Under NEP-171 these differ, so an account holding an NEP-178 approval could stake someone else's NFT and claim it. Fixed before any exploitation. - Removed an administrative method capable of irreversibly locking every staked NFT, replaced with a paginated cleanup that only touches already-claimed records.
- Privileged methods now require exactly 1 yoctoNEAR, so they cannot be invoked with a function-call access key.
- No private keys on the server. Every state-changing contract operation is performed manually by an administrator via
near-cli; the bot only generates the command. - Emergency recovery methods are deliberately constrained beyond common practice: the recipient is read from contract state rather than passed as a parameter, so the owner can trigger a return but cannot choose who receives the asset. Staking recovery additionally requires a 90-day grace period past unlock.
- Gas budgets set from measured mainnet consumption rather than estimates.
Planned
- Independent third-party audit (premature at current volumes; the natural next step as TVL grows)
- Support for multiple NFT collections — the contract architecture already allows it
- Project website
- ABI schema for nearblocks.io
- Mobile application
Why this matters for NEAR
Onboarding through Telegram. The Mini App removes the main barrier to entry: no wallet extension, no seed-phrase literacy required to start. This is NEAR's abstracted-onboarding thesis put into practice.
Recurring on-chain activity. Staking, trading, leaderboard and notifications together create retention mechanics that generate sustained transactions rather than a one-off spike.
Practical NFT utility. An NFT here is not just an image but an asset that earns yield when staked and can be traded — a working demonstration of NEP-171 in a real user scenario.