Made with ❤️ on TON Blockchain
Lotshot is a decentralized lottery running entirely on the TON blockchain. The smart contracts are written in FunC and managed through a TypeScript tooling stack. Together they deploy an NFT collection and handle a lottery where prizes are paid out in jettons.
The lottery accepts jetton payments for tickets. A random number determines which prize tier is won, and counters limit how many prizes of each level can be issued per round. After the jackpot (10 000 USDT) is won, the lottery continues without pause: no more jackpot payouts, but tickets can still be purchased and other prize levels remain active.
- Run
npm installto install the project dependencies. - Copy
.env.exampleto.envand edit the variables:COLLECTION_OWNER– address that owns the NFT collection.ADMIN_ADDRESS– wallet that manages the lottery.TOKEN_ADDRESS– jetton used to pay for lottery tickets.JET_ADDRESS– address of the deployed Jet contract for admin deposits.TICKET_PRICE– price of one ticket denominated in the jetton.REF_PERCENT– referral payout in basis points.JACKPOT_AMOUNT_USDT– jackpot size (whole USDT) for the USDT lottery (defaults: 10 000 mainnet / 100 testnet).TIMELOCK_DELAY_SEC– timelock delay (in seconds) for USDT withdrawals
(defaults: 172 800 s on mainnet, 3 600 s on testnet).
- Prepare the metadata files
collection.jsonand0.json–7.json, upload them to IPFS and place the resulting link intocollectionConfig.content. - Run
npm run startand choosedeployCollectionto deploy the NFT collection contract. - Adjust
lotteryConfiginscripts/deployJet.tsand selectdeployJetto deploy the lottery contract. - From the same script run
setLotteryAddress()so the lottery contract can mint NFTs.
The repository also provides depositUSDT to deposit liquidity from the admin account. Deposited USDT is locked until the jackpot lock amount has been funded.
The jackpot reserve is locked on the first ticket purchase only; after the jackpot is won, it is never re-locked. All other prizes continue as per their counters.
The deployJet.ts script also exposes withdraw() and two helper functions,
scheduleUSDTWithdrawal() and executeUSDTWithdrawal(), to manage USDT
withdrawals via the timelock. Amounts for these helpers are provided in whole
USDT and TON for convenience.
The lottery issues unique NFTs for every prize tier. Metadata for each token can be found in the lottery_metadata directory and is pinned to IPFS. The collection contract stores the lottery address alongside the owner address, next item index and royalty details. The collection is deployed once and the lottery contract mints the appropriate token when a player wins.
Send a jetton transfer to the lottery wallet with the amount equal to TICKET_PRICE. If you have a referrer, include the 267‑bit address inside the payload. Any overpayment is returned and the referral share is sent to the referrer.
-
After receiving a payment, the contract generates a random number
xfrom 0 to 11 999. -
If
x == 0the contract informs the administrator about a potential jackpot.- the player receives
JACKPOT_PRIZE(10 000 jettons) and NFT0; - the Jackpot counter increases; remaining prize tiers continue as usual.
- the player receives
-
Otherwise
xis checked against the ranges below. A prize is issued while the associated counter is below its limit. The table assumes a round of 12 000 tickets.Range of xCounter limit Prize (jettons) NFT x == 0jp < 110 000 0 x < 4major < 31 800 1 x < 14high < 10700 2 x < 64mid < 50180 3 x < 214low_mid < 15050 4 x < 514low < 30025 5 x < 1704mini < 119010 6 otherwise — 0 7
Note: After the Jackpot is claimed its row is greyed out, but odds and payouts for all other tiers stay the same. Win notifications are broadcast live via @LotshotBot on Telegram/X.
- After the prize is issued, one of the counters
jp,major,high,mid,low_mid,low,miniis increased. The NFT is minted from the collection and the jetton prize is sent to the player. - The contract must always keep at least 0.05 TON and enough jettons for future payouts.
- When sending a ticket, store your TON wallet address first in
forward_payload, followed by an optional referrer address. Setforward_ton_amountto at leastmin_ticket_value(≈0.39 TON).
- FunC for smart contracts
- TypeScript scripts and tests
- @ton/blueprint and ton-sandbox for local development
- Jetton token standard for ticket payments
Lotshot leverages the speed and low fees of The Open Network. Transactions are transparent and immutable, and NFTs are issued directly on-chain.
This project is released under the MIT License. See the LICENSE file for details.
- 🌐 Website
- 🐦 Twitter / X
- 📣 Telegram
- 📝 Medium
Made with ❤️ by the Lotshot team • Built for the TON ecosystem.