Security
Payment Verification
Forlarge never trusts client-reported payments. Every transaction is verified independently on the server:Buyer signs transaction
The buyer signs a USDC transfer in their wallet and broadcasts it to Injective.
Server-side verification
Forlarge’s servers query the Injective network to confirm:
- Transaction exists and is finalized
- Correct USDC amount was transferred
- Payment was sent to the correct creator wallet address
- Payout split matches the active fee policy for the environment
Injective Cosmos Verification
Forlarge queries the Injective LCD REST API.MsgSend bank messages are parsed to verify USDC denom and amount match the expected values. Both native USDC (CCTP via Noble IBC) and legacy Peggy USDC are accepted.
Injective EVM Verification
Forlarge callseth_getTransactionReceipt via the Injective EVM JSON-RPC. The response logs are scanned for ERC-20 Transfer(from, to, amount) events on the USDC contract. The to address is verified against the creator’s inj1 address (converted from bech32 to EVM hex for comparison).
Download Security
- Cryptographically random tokens — download URLs use 32-character nanoid tokens
- Time-limited — tokens expire after 24 hours
- Use-limited — each token allows up to 5 downloads
- Server-side validation — every download request is checked against the purchase record
- No direct file URLs — product files are never publicly accessible without a valid token
Authentication
Email + Password
- Minimum 8-character password enforced at signup (with a strength indicator)
- Passwords hashed via Supabase Auth (bcrypt)
- Email confirmation required
Google OAuth
- Full server-side OAuth flow with canonical base URL resolution
- CSRF protection via state tokens
- Tokens exchanged server-side, never exposed in the browser
Wallet-Based Login
- Nonce-based challenge/response flow for Injective wallets (Cosmos and EVM)
- Public key derivation verified against the claimed
inj1address — prevents cross-address attacks - Nonces are single-use, expire after 5 minutes, and are deleted immediately after verification
- Rate limited: 20 requests/IP/min and 6 requests/wallet/min on the nonce endpoint
Invite Code Security
Invite codes are claimed atomically via theactivate_account_with_invite DB function — a single transaction that validates, claims, and activates in one operation. This prevents race conditions where two concurrent signups could claim the same code.
Rate limiting: 10 invite code validation attempts per hour per IP and per user.
Access Control
Invite-Gated Registration
New creator accounts on forlarge.app require a valid invite code.access_granted is set only after atomic invite validation. The testnet deployment (test.forlarge.app) is login-only — no invite required, access is granted by host detection.
Row-Level Security (RLS)
Supabase RLS policies enforce:- Users can only modify their own profiles and products
- Buyers can only read their own transactions (
buyer_user_idmatch) - Payment records are immutable after creation
- Admin endpoints require server-side admin role verification
- Wallet nonce table is service-role only — no client access
Guest → Account Linking
When a buyer who purchased without an account later signs up with the same email, a DB trigger automatically setsbuyer_user_id on their past transactions. No manual steps required.
Infrastructure Security
- HTTPS everywhere — all traffic encrypted in transit
- Supabase — database and auth on SOC 2 Type II compliant infrastructure
- Secrets as env vars — no API keys or secrets in code
- Service role key server-side only — never exposed to the browser
- CRON_SECRET — all cron endpoints require a Bearer token header
SET search_path = public— allSECURITY DEFINERfunctions hardened against search path injection