// sys.transparency

TRANSPARENCY

How escrow, audits, and admin accountability actually work.

// source.open

NOW SOURCE-OPEN

We're happy to announce that DonutTrade is source-open. The full platform — API, web frontend, bots, escrow logic, admin tooling — lives on GitHub under the Functional Source License (FSL 1.1). Every endpoint, every admin check, every cryptographic operation: all readable, all verifiable.

> github.com/givey999/donuttrade

Available today for reading, learning, and non-commercial use. Auto-converts to Apache 2.0 two years after each release. See LICENSE in the repo for the exact terms.

// data.policy

YOUR DATA

We don't want to store passwords — so we don't. Sign-in goes through Microsoft or Discord OAuth. DonutTrade never sees your password. You'll notice scaffolding for an email+password sign-in path in the repo — we're intentionally not shipping it, precisely because we don't want to be in the business of storing credentials.

What we store

  • ·Minecraft username (entered during sign-up)
  • ·Microsoft account ID (if you sign in with Microsoft)
  • ·Discord user ID + username (if you link or sign in with Discord)
  • ·Email address (from Microsoft or Discord OAuth, when your account has one — stored in users.email, nullable)
  • ·Your server-side session token, IP address, and user-agent (short-lived, expires on logout)
  • ·Deposit, withdrawal, and trade history (required for the audit log)
  • ·Your current escrow inventory (required to know what’s yours)
  • ·Notification preferences (DM opt-in / opt-out)

What we receive from Microsoft

When you sign in with Microsoft, we request the openid, email, profile, and offline_access scopes. From the returned ID token we extract your Microsoft account ID and, if present, your email address.

We store the Microsoft account ID to identify you on future logins, and the email address in the users table (nullable — not all Microsoft accounts include one).

The Microsoft access token is used once at sign-in and never stored.

What we receive from Discord

If you link or sign in with Discord, we request the identify and email scopes. From /users/@me we receive your Discord user ID, username, and email address (if your Discord account has one verified).

We store your Discord user ID and username. The email is stored in the shared users.email field.

We do not read your messages, server list, friend list, or any other Discord content.

You can unlink Discord at any time from /dashboard.

What we never touch

  • ·Real names or physical addresses
  • ·Phone numbers
  • ·Payment cards or real-money financial data — DonutTrade only handles in-game DonutSMP currency
  • ·Browser fingerprints or ad-targeting profiles
  • ·Your Microsoft or Discord password (handled entirely by those providers)
// escrow.flow

HOW AN ESCROW TRADE WORKS

escrow.flow — example trade
[t=0]    buyer.submit_order(item=zombie_spawner, price=45000)
[t=0.01] api.issue_code(order_id=42, hmac=sha256(payload + CODE_SIGNING_SECRET))
[t=0.02] escrow.lock_funds(buyer, amount=45000)
[t=1h]   seller.submit_fill(order_id=42, code=<verified>)
[t=1h]   escrow.verify_hmac(order_id, code) → OK
[t=1h]   escrow.release_to_seller(amount=44100)   // -2% platform fee
[t=1h]   escrow.deliver_item(buyer)
[t=1h]   audit.log(action=trade_completed, order_id=42)

Every line above corresponds to a real function call. Grep packages/api/src/ in the public repo to find them — starting with packages/api/src/lib/deposit-code.ts for the HMAC generation.

// admin.acl

ADMIN POWERS

ADMINS CAN

  • Approve deposits (verify items match the claimed amount)
  • Confirm withdrawals (deliver items in-game)
  • Resolve disputes (review audit log, render a decision)
  • Freeze accounts suspected of scamming
  • Adjust platform settings (fees, categories, limits)

ADMINS CANNOT

  • Move items a user didn't deposit
  • Edit or delete audit log rows (append-only)
  • Drain escrow without a matching order
  • See your password — Microsoft and Discord handle sign-in entirely; we never receive your credentials
  • Block a user's withdrawal on their own authority — all withdrawals require a recorded admin action
// audit.log

EVERY ACTION IS LOGGED

audit.log — example entries
TIMESTAMPUSERACTIONTARGETMETADATA
2026-04-14 14:32:01xDarkKnightdeposit_code_issuedzombie_spawner ×3DT-DEP-xJk...Lm
2026-04-14 14:35:47admin@platformdeposit_approvedDT-DEP-xJk...Lmverified_in_game
2026-04-14 14:40:12xDarkKnightorder_createdorder_id=42price=45000
2026-04-14 15:12:08CraftMaster99order_filledorder_id=42hmac=OK
2026-04-14 15:12:08escrow.servicefunds_releasedCraftMaster99amount=44100
2026-04-14 15:45:30CraftMaster99withdrawal_requestedDT-WTH-p8Q...Rnamount=44100
2026-04-14 16:02:11admin@platformwithdrawal_confirmedDT-WTH-p8Q...Rndelivered_in_game
2026-04-14 16:02:12systemtrade_completedorder_id=42fee=900

The audit log is append-only at the database level. Admins — including the platform owner — cannot edit or delete rows. Your real activity lives at /dashboard. Example rows shown above are illustrative.

// dispute.flow

IF SOMETHING GOES WRONG

  1. 01Open a ticket in our Discord.
  2. 02An admin reviews the audit log for your account and the counterparty.
  3. 03Decision rendered within 24 hours.
  4. 04If you disagree, escalate to the platform owner in Discord — same 24-hour window.
  5. 05Chargebacks and refunds are paid from the platform's reserve, not from other users' escrow.
// crypto.math
HOW DEPOSIT CODES WORK (click to expand)

Deposit and withdrawal codes are signed with HMAC-SHA256 using a secret that lives only on the server. Only the server can create a valid code. Even an admin, without the secret, cannot forge one.

// packages/api/src/lib/deposit-code.ts
const payloadStr = Buffer.from(JSON.stringify(fullPayload)).toString('base64url');
const signature = createHmac('sha256', config.CODE_SIGNING_SECRET)
  .update(payloadStr)
  .digest('base64url');

return {
  code: `${prefix}${payloadStr}.${signature}`,
  expiresAt,
};

The full implementation (including verifyCode with timing-safe comparison) is in packages/api/src/lib/deposit-code.ts in the public repo.

// revenue.model

HOW WE MAKE MONEY

TRADE FEES

2% of each completed trade, shown in the UI at order creation. Split between buyer and seller.

SPONSORED LISTINGS — COMING SOON

Item sellers will be able to pay for top placement on the marketplace. Sponsored rows will be tagged SPONSORED. Not yet live.

AD PLACEMENTS

Occasional banner ads from DonutSMP-adjacent services, arranged through Discord tickets. Not programmatic; we know every advertiser.

We don't sell your data · We don't profile users · We don't tax trades hidden in the spread

// operator.id

WHO RUNS THIS

DonutTrade is run by givey999. Reach out directly on Discord — the link is in the footer.