"Every token launch, NFT drop, and auction on Solana is front-run before it settles. SealBid makes that cryptographically impossible."
SealBid is a MEV-proof auction primitive for Solana. It solves a fundamental protocol-level flaw in every on-chain auction today: bids are public the moment they're submitted, which means bots can read your bid in the mempool, outbid you by 1 lamport, and you lose every time.
This isn't a UI problem. No frontend fix can solve it. SealBid solves it at the protocol layer using a commit-reveal scheme — bids are cryptographically hidden until the commit window closes, making front-running impossible by design.
SealBid is not a DEX or a marketplace. It is a general primitive — an SDK that any Solana dApp can plug into in under 50 lines of code.
Every on-chain auction on Solana today works like this:
- Bidder submits a bid transaction
- The transaction is visible in the mempool before it settles
- A bot reads the bid, constructs a higher bid, and gets it included first
- The honest bidder loses — every time
This affects:
- NFT drops and sales
- Token launches and IDOs
- On-chain job markets and freelance boards
- Any dApp that requires competitive bidding
Existing solutions like Darklake address this at the DEX level. SealBid is a 10x larger story — a general primitive that any dApp can use.
SealBid uses a three-phase commit-reveal protocol.
The bidder generates a cryptographic commitment client-side:
commitment = keccak256(bid_amount || salt)
Only the hash goes on-chain. USDC is locked in a PDA escrow. No one — not bots, not validators — can read the bid amount from the commitment hash.
After the commit window closes, bidders submit their plaintext bid_amount and salt. The Solana program verifies:
hash(bid_amount || salt) == stored_commitment
If a bidder fails to reveal within the reveal window, their bond is slashed. This is the anti-griefing mechanic that prevents commit-without-reveal attacks.
The highest valid revealed bid wins. Tokens transfer via SPL. All losing bidders receive their USDC refunded atomically in the same transaction.
┌─────────────────────────────────────────────────────────┐
│ Frontend │
│ Next.js 14 + TypeScript + Wallet Adapter │
│ │
│ commitment = keccak256(bid_amount || salt) │
│ (computed in browser — raw bid never leaves client) │
└────────────────────────┬────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ SealBid SDK │
│ TypeScript wrapper library │
│ │
│ SealBid.create() — initialize auction │
│ SealBid.commit() — submit commitment + lock funds │
│ SealBid.reveal() — submit plaintext bid + salt │
│ SealBid.settle() — resolve winner, refund losers │
└────────────────────────┬────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Solana Smart Contract │
│ Rust + Anchor │
│ │
│ Instructions: │
│ commit_bid — store hash, lock USDC in PDA │
│ reveal_bid — verify hash, record plaintext bid │
│ settle_auction — pick winner, atomic SPL transfers │
│ │
│ Accounts: │
│ Auction PDA — auction state, timing, config │
│ Bidder PDA — per-bidder commitment + escrow │
└─────────────────────────────────────────────────────────┘
| Layer | Technology |
|---|---|
| Smart Contract | Rust, Anchor Framework |
| Token Transfers | SPL Token Program |
| State Management | Program Derived Addresses (PDAs) |
| Frontend | Next.js 14, TypeScript |
| Wallet Integration | Solana Wallet Adapter (Phantom, Backpack) |
| Client-side Hashing | @noble/hashes (keccak256) |
| Network | Solana Devnet / Mainnet |
Three instructions handle the entire auction lifecycle.
pub fn commit_bid(
ctx: Context<CommitBid>,
commitment: [u8; 32], // keccak256(bid_amount || salt)
escrow_amount: u64, // USDC locked — must be >= max possible bid
) -> Result<()>- Stores commitment hash in the bidder's PDA
- Transfers USDC from bidder wallet to escrow PDA
- Reverts if commit window has closed
pub fn reveal_bid(
ctx: Context<RevealBid>,
bid_amount: u64,
salt: [u8; 32],
) -> Result<()>- Recomputes
keccak256(bid_amount || salt)on-chain - Verifies it matches the stored commitment
- Records
bid_amountas the bidder's valid bid - Slashes bond if called outside the reveal window
pub fn settle_auction(
ctx: Context<SettleAuction>,
) -> Result<()>- Iterates all revealed bids, picks highest
- Transfers tokens to winner via SPL
- Refunds all losing bidder escrows atomically
- Marks auction as settled
Any Solana dApp can integrate SealBid in under 50 lines:
import { SealBid } from "@sealbid/sdk";
import { keccak256 } from "@noble/hashes/sha3";
const client = new SealBid({ connection, wallet });
// 1. Create an auction
const auction = await client.create({
tokenMint: MINT_ADDRESS,
tokenAmount: 100,
commitDuration: 300, // 5 minutes
revealDuration: 180, // 3 minutes
});
// 2. Commit a bid (hash computed client-side, raw bid never leaves browser)
const salt = crypto.getRandomValues(new Uint8Array(32));
const commitment = keccak256(encode(bidAmount, salt));
await client.commit({
auctionId: auction.id,
commitment,
escrowAmount: bidAmount,
});
// 3. Reveal after commit window closes
await client.reveal({
auctionId: auction.id,
bidAmount,
salt,
});
// 4. Settle — winner gets tokens, losers get refunds
await client.settle({ auctionId: auction.id });SealBid is purpose-built for Solana because:
- PDAs allow deterministic, per-bidder escrow accounts without a central custodian
- Atomic multi-instruction transactions let settlement and refunds happen in a single transaction
- SPL Token Program handles USDC and token transfers natively
- Sub-second finality makes the reveal phase fast enough to be practical in a real auction
The same design is significantly more cumbersome on Ethereum.
| Project | Scope | Approach | Limitation |
|---|---|---|---|
| Darklake | DEX only | Order privacy | Single use case |
| Urani | DeFi layer | MEV discouraged | Not cryptographic |
| SealBid | Any dApp | MEV impossible | — |
- Darklake is DEX-specific. SealBid is a general primitive.
- Urani discourages MEV at the app layer. SealBid makes it cryptographically impossible.
- ZK-based approaches (e.g., ProofPass) require off-chain proving infrastructure. SealBid uses only on-chain hashing — no circuits, no oracles, no trusted setup.
The live demo shows the difference in two side-by-side browser tabs.
Normal auction:
- Bidder A submits a bid
- Bot reads the bid in the mempool
- Bot submits a higher bid and wins
- Bidder A loses — every time
SealBid auction:
- Bidder A submits a commitment hash — bot sees nothing
- Commit window closes
- Both bidders reveal
- Winner is settled on-chain, loser refunded instantly
The demo also shows the SDK integration — one file, under 50 lines, dropping SealBid into an existing dApp.
Because SealBid is a primitive, not a product, any Solana dApp can use it:
- NFT marketplaces — sealed-bid NFT auctions, no sniper bots
- Token launchpads — fair IDO allocation, no front-running
- Freelance / job boards — blind bid job markets on-chain
- Grant programs — transparent but private proposal funding rounds
- DAO governance — sealed voting before public tally
sealbid/
├── programs/
│ └── sealbid/
│ └── src/
│ ├── lib.rs # Program entry point
│ ├── instructions/
│ │ ├── commit_bid.rs
│ │ ├── reveal_bid.rs
│ │ └── settle_auction.rs
│ └── state/
│ ├── auction.rs
│ └── bidder.rs
├── sdk/
│ └── src/
│ ├── index.ts # SealBid client
│ ├── commit.ts
│ ├── reveal.ts
│ └── settle.ts
├── app/
│ ├── pages/
│ │ ├── index.tsx # Auction list
│ │ ├── create.tsx # Create auction
│ │ └── auction/[id].tsx # Bid + reveal UI
│ └── components/
│ ├── CommitForm.tsx
│ ├── RevealForm.tsx
│ └── AuctionStatus.tsx
├── tests/
│ └── sealbid.ts # Anchor integration tests
├── Anchor.toml
└── package.json
- Rust (
rustup) - Solana CLI (
solana-install) - Anchor CLI (
cargo install --git https://github.com/coral-xyz/anchor anchor-cli) - Node.js 18+
# Clone the repo
git clone https://github.com/your-username/sealbid
cd sealbid
# Install dependencies
npm install
# Build the Anchor program
anchor build
# Run tests on local validator
anchor test
# Deploy to devnet
anchor deploy --provider.cluster devnetcd app
npm install
npm run devOpen http://localhost:3000.
| Property | Guarantee |
|---|---|
| Bid confidentiality | Bids are hidden until commit window closes — no on-chain or mempool leakage |
| Commit binding | A bidder cannot change their bid after committing — the hash binds them |
| Reveal enforcement | Non-reveal results in bond slash — griefing is economically punished |
| Atomic settlement | Winner transfer and loser refunds happen in one transaction — no partial states |
| No trusted third party | All logic is on-chain — no oracle, no off-chain server, no admin key |
SealBid deliberately avoids unnecessary cryptographic complexity. Commit-reveal is well-understood, auditable, and buildable. The innovation is applying it as a general Solana primitive with:
- A clean SDK abstraction
- A bond/slash mechanism for reveal enforcement
- Atomic SPL settlement in a single instruction
No ZK circuits. No off-chain provers. No trusted setup. Just hash functions and PDAs.
SealBid was built as a hackathon project targeting the Solana ecosystem. The design prioritizes:
- Demonstrability — the problem and solution are visible in a live demo
- Defensibility — the cryptography is simple enough to explain and audit under questioning
- Generality — it is infrastructure, not a single application