Choose the physical miner you want UNetMine to model. Plus expands the available machine library; your signed-in server account controls access.
UNetMine estimates what the selected physical miner would produce today, subtracts modeled electricity and pool costs, and shows the resulting NET MINE amount as a purchase target you control.
Compares the physical-miner economics frozen in your Production Ledger with what you actually recorded through UNetMine. It uses recorded miner-days only—no invented uptime, resale value, or electrical-installation cost.
When you record Match, Adjust, or Pass, UNetMine freezes that day’s modeled economics. Later price or network changes do not rewrite the historical row.
Creates a verified UNetMine account. Supabase sends the verification email.
Use the same verified account from any browser once the front end is hosted.
Accounts currently exist only in this browser.
Production Ledger, reserve, miner choice and trial state must survive device changes.
The browser cannot be trusted to enforce trial dates in production.
Current C$7.99/month and C$79/year choices are simulated only.
Expired users should keep access to history while new miner-days remain blocked.
Do not over-engineer this before there is meaningful trial abuse.
POST /api/billing/checkout — create hosted checkout sessionGET /api/billing/status — return trial / active / past_due / canceled / expiredPOST /api/billing/webhook — provider updates server-side subscription statusPOST /api/billing/portal — open customer billing-management portalIdentity and account lifecycle only.
user_id — stable internal IDemail — verified login identitydisplay_name — optional greeting nametimezone — account-local day boundary for miner-day lockingcurrency_code — CAD / USD / etc.created_at / last_login_ataccount_status — active / disabledThe user’s selected machine and modeling preferences.
miner_key — s21pro / z15 / s19xp / z11power_rate_cad_kwhpool_fee_pctpurchase_destination — Kraken / Coinbase / Otherupdated_atAccounting only; no funds are held by UNetMine.
starting_cadremaining_cadspent_cadmatched_coin_totalsupdated_atImmutable historical settlements after the day is recorded.
miner_day_iduser_id + local_date + miner_keygross_coin / net_target_coinsettlement_type — match / adjust / passsettled_coin / settled_cadrecorded_atServer time becomes the authority for the 90-day trial.
trial_started_attrial_expires_atentitlement — trial / active / read_onlyplan — monthly / annual / nonesubscription_statusUseful for reproducibility, but not a custody or trade record.
coin_price_cadnetwork_hashratemodeled_issuancehardware_profile_versionsnapshot_timestampUNetMine does not need them.
Billing provider should own payment-card handling.
{
"user": {
"user_id": "usr_...",
"email": "verified@example.com",
"display_name": "Ken",
"timezone": "America/Edmonton",
"currency_code": "CAD"
},
"setup": {
"miner_key": "z15",
"power_rate_cad_kwh": 0.07,
"pool_fee_pct": 2.0,
"purchase_destination": "Kraken"
},
"reserve": {
"starting_cad": 4000.00,
"remaining_cad": 3943.46,
"spent_cad": 56.54
},
"miner_day": {
"local_date": "2026-10-04",
"miner_key": "z15",
"net_target_coin": 0.018390,
"settlement_type": "match",
"settled_coin": 0.018390,
"settled_cad": 52.53,
"locked": true
},
"entitlement": {
"trial_started_at": "...",
"trial_expires_at": "...",
"plan": "monthly",
"subscription_status": "active"
}
}
Verified identity, login lifecycle and profile settings.
POST /api/auth/signupPOST /api/auth/loginPOST /api/auth/logoutPOST /api/auth/verify-emailPOST /api/auth/reset-passwordGET /api/meSelected virtual miner and modeling preferences.
GET /api/setupPUT /api/setupGET /api/machinesGET /api/machines/:keyOne settlement per local date + miner, enforced on the server.
GET /api/miner-day/todayPOST /api/miner-day/settleGET /api/ledgerGET /api/ledger/:idAccounting reserve only; no custody or wallet balance.
GET /api/reservePUT /api/reserveGET /api/reserve/historyCurrent market/network inputs and reproducible model snapshots.
GET /api/economics/:minerKeyGET /api/prices/:coinGET /api/network/:coinCheckout and entitlements remain external to miner economics.
POST /api/billing/checkoutGET /api/billing/statusPOST /api/billing/webhookPOST /api/billing/portalPOST /api/miner-day/settle
Request:
{
"miner_key": "z15",
"settlement_type": "match",
"requested_coin": 0.018390,
"client_local_date": "2026-10-04"
}
Server checks:
1. authenticated user
2. verified email
3. trial / subscription entitlement
4. account timezone
5. selected miner is allowed
6. no existing settled row for user + local_date + miner_key
7. current reserve is sufficient
8. current economics snapshot is valid
Response:
{
"status": "recorded",
"miner_day_id": "md_...",
"locked": true,
"settled_coin": 0.018390,
"settled_cad": 52.53,
"reserve_remaining_cad": 3943.46
}
Verified account identity and local-day settings.
id UUID PKemail CITEXT UNIQUE NOT NULLdisplay_name TEXTtimezone TEXT NOT NULLcurrency_code CHAR(3) NOT NULL DEFAULT 'CAD'email_verified_at TIMESTAMPTZaccount_status TEXTcreated_at / last_login_at TIMESTAMPTZVersioned miner specifications used by the economics engine.
key TEXT PKname TEXTcoin TEXTalgorithm TEXThashrate NUMERICpower_w NUMERICtier TEXT — public / plusprofile_version INTactive BOOLEANOne current modeling setup per user.
user_id UUID PK FK → users.idminer_key FK → machine_profiles.keypower_rate NUMERICpool_fee_pct NUMERICpurchase_destination TEXTupdated_at TIMESTAMPTZVirtual Hardware Reserve accounting only.
user_id UUID PK FK → users.idstarting_cad NUMERICremaining_cad NUMERICspent_cad NUMERICcoin_totals JSONBupdated_at TIMESTAMPTZImmutable historical production + settlement records.
id UUID PKuser_id UUID FKlocal_date DATEminer_key TEXT FKgross_coin / net_target_coin NUMERICelectricity_cad / pool_fee_coin NUMERICsettlement_type TEXTsettled_coin / settled_cad NUMERICeconomics_snapshot JSONBlocked BOOLEAN DEFAULT TRUErecorded_at TIMESTAMPTZTrial and access state controlled by the server.
user_id UUID PK FKtrial_started_at TIMESTAMPTZtrial_expires_at TIMESTAMPTZentitlement TEXT — trial / active / read_onlyplan TEXT — monthly / annual / noneupdated_at TIMESTAMPTZProvider-facing subscription status, never card details.
id UUID PKuser_id UUID FKprovider_customer_id TEXTprovider_subscription_id TEXT UNIQUEplan TEXTstatus TEXTcurrent_period_end TIMESTAMPTZcancel_at_period_end BOOLEANupdated_at TIMESTAMPTZIdempotent webhook/event processing history.
provider_event_id TEXT PKevent_type TEXTuser_id UUIDpayload JSONBprocessed_at TIMESTAMPTZUNIQUE (user_id, local_date, miner_key) on miner_days.
This is the database-level protection behind the one-settlement-per-day rule.
CREATE TABLE miner_days (
id UUID PRIMARY KEY,
user_id UUID NOT NULL REFERENCES users(id),
local_date DATE NOT NULL,
miner_key TEXT NOT NULL REFERENCES machine_profiles(key),
gross_coin NUMERIC(24,12) NOT NULL,
net_target_coin NUMERIC(24,12) NOT NULL,
electricity_cad NUMERIC(14,4) NOT NULL,
pool_fee_coin NUMERIC(24,12) NOT NULL,
settlement_type TEXT NOT NULL CHECK (settlement_type IN ('match','adjust','pass')),
settled_coin NUMERIC(24,12) NOT NULL DEFAULT 0,
settled_cad NUMERIC(14,4) NOT NULL DEFAULT 0,
economics_snapshot JSONB NOT NULL,
locked BOOLEAN NOT NULL DEFAULT TRUE,
recorded_at TIMESTAMPTZ NOT NULL DEFAULT now(),
UNIQUE (user_id, local_date, miner_key)
);
CREATE TABLE subscriptions (
id UUID PRIMARY KEY,
user_id UUID NOT NULL REFERENCES users(id),
provider_customer_id TEXT,
provider_subscription_id TEXT UNIQUE,
plan TEXT CHECK (plan IN ('monthly','annual')),
status TEXT NOT NULL,
current_period_end TIMESTAMPTZ,
cancel_at_period_end BOOLEAN NOT NULL DEFAULT FALSE,
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
Implement the locked Brick #20 schema and real verified accounts.
Replace browser-local state with authenticated API reads and writes.
The server must decide whether a settlement is valid.
Trial timing must not depend on browser storage.
Use hosted checkout for C$7.99/month and C$79/year.
Once backend states are real, remove simulated trial/billing controls.
Invite a small number of real users before public promotion.
No server state loaded yet.