Your first trade
Nullbook lets two people agree on a price for a Solana token and exchange it for SOL. You can bring your own buyer or find one on the marketplace.
- Research the token in Markets. Check its mint address so you know exactly what you are buying or selling.
- Choose how to meet. Post a listing or bid in Marketplace. If you already know the buyer, open Private deals and send them an invitation.
- Both traders set up a private wallet and inbox, review the terms in the same deal room, and agree on the latest revision.
- Each trader funds their own private balance. Both verify the payouts and sign one transaction. Look for Settled and the finalized receipt before treating the trade as complete.
You can browse tokens and listings without a wallet. Bidding or accepting terms does not move funds. Registering onchain, depositing, exchanging and withdrawing use real assets on Solana mainnet.
Find a token and read its price
Markets shows Birdeye data for Solana tokens. Use it to compare an offer with a reference price, then check the mint and units before you trade.
Use Search token to look up a name or paste a mint address. The token page shows price, liquidity and market activity. Pool impact estimates how a sale of a given size might move a pool; liquidity changes, so the estimate is not a quote you can execute.
| What the field means | Example |
|---|---|
| Token mint identifies the asset. Names and tickers can be reused. | Compare the full mint address on the token page, the bid and the room. A mint is not a wallet to send funds to. |
| Token quantity is entered in the smallest units of that mint. | For a token with 6 decimals, enter 1500000 to trade 1.5 tokens. Check mint or Check mint and units shows the decimals. |
| The bid or invitation’s SOL price is the total for the entire quantity. | An offer of 0.02 SOL for 1.5 tokens costs 0.02 SOL in total before fees. In wallet forms that ask for base units, 0.02 SOL is 20000000 lamports. |
If a token is missing, Add token lets a connected wallet submit its mint for discovery after a live pool check. This does not post a sale or register the mint for private transfers. New private trades require a mint registered with the privacy program: classic SPL tokens and plain Token-2022 mints without extensions are supported.
Set up your wallet and inbox
Your connected account identifies you to other traders. A separate private wallet owns the assets you deposit and signs the exchange.
- Open Private deals and connect a Solana wallet through Privy. Share this connected address if a seller wants to invite you.
- In Private wallet, choose Create backup. Enter a passphrase of at least 12 characters, generate the encrypted backup, and download the file. Choose Unlock from backup and open that file with the passphrase before sending any funds.
- Choose Open encrypted inbox and then Register inbox on first use. The signatures link this account and backup to the inbox where you receive bids and invitations. They do not transfer funds.
- To make private payments, fund your own displayed Public mainnet address with SOL for network costs. In Private wallet, review and confirm Register on mainnet. This publishes the keys the protocol needs to receive private funds; inbox registration alone does not do that.
Keep both the original backup and its passphrase. Signing back into Privy restores access to the connected account, not the separate private wallet. A new backup creates a different wallet.
Post a listing or bid privately
Use Marketplace when you want buyers to come to you. The listing is public; each buyer proposes their quantity and SOL price privately.
| Listing format | When the seller can review bids |
|---|---|
| Open bids | As bids arrive. The seller can choose a bid before the deadline. |
| Sealed auction | After bidding closes. The service withholds bidders’ identities and encrypted bids from the seller until then. The highest bid does not win automatically. |
- Seller: choose Post a listing, enter the mint, select a bidding format and deadline, then Publish listing. Copy listing link to share it. The listing shows the mint, seller address, format, deadlines and total number of bids submitted. It does not advertise a fixed quantity or reserve tokens.
- Buyer: open View listing, unlock your registered inbox, enter the token quantity in smallest units and your total offer in SOL, then Send encrypted bid. You can withdraw a pending bid and submit another while bidding is open.
- Seller: open My activity, select the listing and choose Review bid to verify the offer. Decline it, close without choosing, or use Choose this bid. Choosing closes the listing to other buyers and opens one private room with the selected buyer.
- Both traders: return through My activity or Your deals. In the room, the seller can accept the buyer’s bid or counter its quantity or price. The mint stays fixed. The room expires 24 hours after bidding closes, even if a bid was chosen early.
A listing can lead to only one deal. To sell separate lots to different buyers, create separate listings. The public bid count includes submissions that were later withdrawn or declined.
Invite a buyer and negotiate
Use a direct invitation when you know the buyer’s connected wallet address. Both traders must already have registered their inboxes.
- Seller: choose Invite a buyer in Private deals. Enter the buyer’s connected address, token mint, quantity in smallest units, and total price in SOL. Send encrypted invitation creates the room.
- Buyer: open the invitation under Your deals or follow the seller’s invitation link. Only the two registered accounts can open the room. A forwarded invitation link does not give someone else access.
- Review the mint, quantity, SOL total, fee, payout addresses and expiry. The recipient of the latest offer can choose Accept these terms or Counteroffer. A counter creates a new revision for the other trader to review.
A direct invitation lasts 24 hours from creation. Counters do not restart the clock. Unlike a marketplace room, a direct counter can propose a different mint. Acceptance records the agreement; each party still has to fund and sign.
Fund your side of the deal
The seller needs the token. The buyer needs the agreed SOL total plus any desk fee. Each funds their own private wallet and keeps public SOL available for network costs.
- Use the Public mainnet address in your own Private wallet panel. Make the token or SOL available on the public side of that wallet first. Do not send the trade amount directly to the other trader.
- Under Deposit or withdraw on mainnet, enter the asset and amount in base units. Choose Review public deposit, check the address and amount, then Confirm mainnet deposit.
- Read balances and find the private balance for that exact asset. In the accepted room, choose Verify my funding. The exchange can be prepared after both traders do this.
Example: for a sale of 1.5 six-decimal tokens at 0.02 SOL, the seller needs 1500000 token units privately. With no desk fee, the buyer needs 20000000 lamports privately plus separate public SOL for network costs. A public balance alone does not fund the private trade. Verification does not lock funds; spending them elsewhere can cause the exchange to fail.
Sign and confirm the exchange
Nullbook uses the existing Helius Solana Privacy Rings program to exchange both assets in one transaction. The token and SOL move together, or neither transfer takes effect.
- Both traders choose Prepare my side. Each wallet builds proof of its proposed transfer. Once both proofs are available, the buyer chooses Open signing window.
- Each trader selects Verify payouts and sign. The wallet checks its expected incoming asset, amount and recipient, checks any desk fee, and simulates the whole exchange before signing. Both must sign the same transaction.
- Either trader can choose Submit signed exchange. If you are waiting, use Check settlement onchain. Settled and View finalized mainnet transaction mean Nullbook verified a successful mainnet receipt matching the trade.
A login signature, an accepted offer, and even two settlement signatures do not prove a trade landed. If submission times out, check the original receipt before trying to move the same funds again.
Fees and the buyer’s total
Posting a marketplace listing, bidding, and choosing a buyer carry no Nullbook fee. Review the desk fee and network costs separately before funding.
| Cost | Who pays and how |
|---|---|
| Desk fee | Zero if no fee recipient is configured. Otherwise the buyer pays 0.5% on top of the agreed SOL price, rounded down to whole lamports. The room shows the fee and recipient. |
| Settlement network fee | The buyer’s private wallet pays from its public SOL balance, even when the seller submits the signed exchange. |
| Wallet operations | Each trader pays the onchain costs of their own registration, deposits and withdrawals. Keep public SOL available for these actions. |
On a 2 SOL sale with the desk fee enabled, the seller receives 2 SOL and the buyer supplies 2.01 SOL privately. The 0.01 SOL desk fee is separate from the network fee.
Who can see a trade?
Private terms keep the price and size out of the public listing. They do not hide every relationship or make a trader anonymous.
| Who | What is visible |
|---|---|
| Marketplace visitors | The listed mint, seller address, format, deadlines and bid count. Visitors do not see bid prices, quantities or bidder addresses. Direct invitations never appear here. |
| Buyer and seller | Their shared terms, accounts and payout addresses. If a desk fee is charged, verifying its output can also reveal the buyer’s change on that transfer to the seller. |
| Nullbook’s service | Who bid on which listing and when, room participants, status and final transaction signature. Bid terms, counters and signing packets reach the service encrypted. The service controls when sealed bids are released. |
| Public chain observers | The transaction signers and timing. Public deposits and withdrawals reveal amounts and addresses. Reusing a private wallet can link activity across deals. |
| The Helius prover | Private inputs needed for a proof are processed in an attested enclave, a protected computing environment that the wallet verifies before use. |
Find your activity and read a status
Marketplace → My activity shows your listings and bids. Private deals → Your deals shows your rooms. Reopen a room to see its current revision, next action or finalized receipt.
| Room status | What it means |
|---|---|
| In negotiation | The recipient can accept or counter the current revision. |
| Accepted | The terms are agreed. Both traders still need to verify funding. |
| Preparing exchange | Both marked their funding ready. Proofs and signatures may still be needed. |
| Awaiting settlement | Both approved the same transaction. Submit or check its receipt; finalization may still be pending. |
| Settled | A matching successful transaction has finalized. Open the receipt and read your updated balance. |
| Closed or Expired | The room was closed before a settlement packet was sent, or its deadline passed before both approvals. Closing a room does not withdraw deposits. An already co-approved trade can still have its receipt checked. |
Wallets looks up an address’s public SOL and tokens. Positions shows the connected wallet’s token holdings, its offers and coins it added. Offers and History show the separate public order book and its activity. That older order book cannot post or fill live trades; private bids, balances and receipts belong in Marketplace or Private deals.
Recover funds and resolve problems
An unspent deposit stays in your own private wallet if the other trader leaves. Restoring and withdrawing it does not require their signature.
- First check any signing activity. Before settlement packets are exchanged, Close deal without trading is available. Closing the page or locking a wallet cannot revoke a signature already shared. If submission may have happened, check the original receipt.
- Choose Unlock from backup with the original encrypted file and passphrase. Read balances, then enter the asset, base-unit amount and intended public mainnet destination. A blank withdrawal address defaults to the restored wallet’s own public address.
- Choose Review public withdrawal and check the destination and amount before Confirm mainnet withdrawal. The withdrawal and its amount are public. If the app is unavailable, the repository’s standalone recovery tool can read balances or withdraw with your backup, passphrase, Helius access and public SOL for fees.
| Problem | What to check |
|---|---|
| Invitation missing or room will not open | Use the connected address the seller invited and the original backup registered to it. A new backup cannot decrypt the old room. |
| Funds visible but preparation fails | Check the private balance for the exact mint and any desk fee. Funds may already be spent or split across too many private notes. A mint’s freeze authority or unsupported extensions can also affect transfers. |
| Signing window expired | Before either approval, the buyer can refresh the signing window. After an approval, resolve the original transaction and let its signing window expire before reusing those funds. |
| Backup or passphrase missing | Nullbook cannot recreate either one. Privy login, a wallet address and an invitation link cannot restore the separate private spending key. |
Mainnet risks and verification
This is a mainnet app. Onchain operations can change real balances, even when you run the interface locally.
Check the full mint, decimals, total SOL price, fee and payout addresses in the latest room revision. A market listing does not certify a token or guarantee liquidity. A spent balance, expired signing window, stale indexer or unavailable prover can prevent completion.
Automated checks exercised direct invitations and two competing marketplace bids through selection, counteroffer and acceptance. Read-only checks verified mainnet connectivity and the prover. Those checks did not complete a funded mainnet exchange or recovery withdrawal. The settlement code has not been independently audited.
For operators
The web app, API and PostgreSQL database coordinate trades. Private-wallet keys stay with traders. The private exchange uses an existing Solana program; there is no Nullbook contract to deploy.
- From the repository root, use Node 24, pnpm 11 and PostgreSQL 17 or later. Run pnpm install. On first setup, copy .env.example to .env and apps/web/.env.example to apps/web/.env.local without replacing existing credentials.
- Configure the database, Birdeye key and mainnet RPC/Helius privacy access on the server. Configure the public Privy app ID for the web build. Keep provider keys, private keys and Privy secrets out of browser variables; leave the legacy SOLANA_PROGRAM_ID unset.
- Start the database with docker compose up -d, then run pnpm db:migrate and pnpm dev. The default web address is localhost:3000 and the API listens on port 4000. If the web port changes, use the address printed by the dev server.
The repository’s README.md covers installation. Use pnpm privacy:check to verify the mainnet connection without moving funds; pnpm privacy:recover starts the standalone recovery tool when given an encrypted mainnet backup file. The developer reference describes the API, room encryption and receipt checks. Nullbook runs its own marketplace and does not share an order book with Rings OTC.