Expand live money launch requirements

This commit is contained in:
Theodore Song
2026-07-12 17:07:07 -04:00
parent f66155da69
commit b4a1cd709e
5 changed files with 158 additions and 24 deletions
+23 -1
View File
@@ -1,17 +1,32 @@
# Cloud state
BLOB_READ_WRITE_TOKEN=
PMA_STATE_PATH=shared/state.json
PRODUCTION_APP_URL=https://polymarket-site-eta.vercel.app
# Live-money feature gate
# Keep false until legal/compliance approval, provider credentials, wallet signing,
# payment rails, and audit logging are production-ready.
LIVE_TRADING_ENABLED=false
# Accounts / authentication
AUTH_PROVIDER=
DATABASE_URL=
SESSION_SECRET=
ENCRYPTION_KEY=
# Eligibility / compliance provider
KYC_PROVIDER=
KYC_API_KEY=
KYC_WEBHOOK_SECRET=
SANCTIONS_PROVIDER=
SANCTIONS_API_KEY=
GEOIP_PROVIDER=
GEOIP_API_KEY=
RESTRICTED_JURISDICTIONS=US,CA-NY,CA-ON
TERMS_VERSION=
PRIVACY_VERSION=
RISK_DISCLOSURE_VERSION=
MARKET_POLICY_STORE=
# Wallet / deposit-wallet provider
WALLET_PROVIDER=
@@ -24,6 +39,7 @@ POLYMARKET_SIGNATURE_TYPE=3
PAYMENTS_PROVIDER=
PAYMENTS_API_KEY=
PAYMENTS_WEBHOOK_SECRET=
WEBHOOK_BASE_URL=
SETTLEMENT_ASSET=pUSD
SETTLEMENT_CHAIN=polygon
@@ -34,7 +50,13 @@ POLYMARKET_CLOB_API_KEY=
POLYMARKET_CLOB_SECRET=
POLYMARKET_CLOB_PASSPHRASE=
# Audit / monitoring
# Records / reconciliation / monitoring
RECONCILIATION_STORE=
ACCOUNTING_EXPORT_STORE=
RATE_LIMIT_STORE=
AUDIT_LOG_STORE=
MONITORING_DSN=
INCIDENT_WEBHOOK_URL=
ADMIN_ALERT_EMAIL=
CUSTOMER_SUPPORT_EMAIL=
RISK_ADMIN_WALLET=
+2 -1
View File
@@ -37,7 +37,8 @@ Use `.env.example` as the setup template.
- `BLOB_READ_WRITE_TOKEN` enables cross-device shared state.
- `/api/live` reports whether KYC, payments, wallet/deposit-wallet, Polymarket
CLOB, audit, and monitoring providers are configured.
CLOB, authentication, geofencing, sanctions, audit, support, and monitoring
providers are configured.
- `LIVE_TRADING_ENABLED` should stay `false` until legal review, provider setup,
wallet signing, reconciliation, and dry-run testing are complete.
- See `REAL_MONEY_ROADMAP.md` for the launch requirements before any real funds
+74 -9
View File
@@ -21,22 +21,34 @@ provider, wallet-signing, reconciliation, and monitoring steps below are done.
- Terms, risk disclosures, privacy policy, and jurisdiction policy.
- KYC / KYB provider.
- Age, location, sanctions, and restricted-market checks.
- Market category policy for elections, sports, finance, crypto, geopolitical
events, manipulated markets, disputed markets, and restricted outcomes.
- Record of user consent to every active terms, privacy, and risk-disclosure
version.
2. Account and wallet
- Real authentication.
- Production account database.
- Password reset, sign-out, session expiry, and optional MFA path.
- Non-custodial wallet connection or Polymarket deposit-wallet flow.
- User-controlled permissions for each agent.
- Revocation path so a user can stop agent trading immediately.
3. Funds
- Deposit provider.
- Withdrawal provider.
- Payment webhooks and failure handling.
- Balance reconciliation, statements, support, and accounting exports.
- Withdrawal review rules for fraud, sanctions, chargeback, and settlement
edge cases.
4. Execution
- Backend order router.
- Polymarket CLOB API credentials.
- EIP-712 order-signing flow.
- Order placement, cancellation, fill tracking, and position reconciliation.
- Idempotency keys, retry policy, rate limits, and stale-order protection.
- Server-side enforcement of user permissions and risk limits.
5. Risk and controls
- Per-agent max allocation.
@@ -45,11 +57,23 @@ provider, wallet-signing, reconciliation, and monitoring steps below are done.
- Manual approval mode.
- Emergency pause and cancel-all.
- Always-available withdrawal path.
- Admin kill switch.
- Market blacklist and category exclusion controls.
6. Audit and monitoring
- Durable append-only audit log.
- Signal, approval, order, fill, cancellation, deposit, and withdrawal events.
- Admin monitoring and incident response.
- Error tracking, uptime monitoring, webhook monitoring, and alert routing.
- Customer support process and data retention policy.
7. Testing and launch operations
- Paper-to-live parity tests.
- Test wallets and dry-run order intents.
- KYC, payments, wallet, CLOB, and webhook integration tests.
- Reconciliation tests for partial fills, cancellations, market resolution,
withdrawals, failed deposits, and duplicate webhooks.
- Rollback plan and incident response drill.
## Environment variables expected by `/api/live`
@@ -60,9 +84,23 @@ production.
- `KYC_PROVIDER`
- `KYC_API_KEY`
- `KYC_WEBHOOK_SECRET`
- `SANCTIONS_PROVIDER`
- `SANCTIONS_API_KEY`
- `GEOIP_PROVIDER`
- `GEOIP_API_KEY`
- `RESTRICTED_JURISDICTIONS`
- `TERMS_VERSION`
- `PRIVACY_VERSION`
- `RISK_DISCLOSURE_VERSION`
- `MARKET_POLICY_STORE`
- `AUTH_PROVIDER`
- `DATABASE_URL`
- `SESSION_SECRET`
- `ENCRYPTION_KEY`
- `PAYMENTS_PROVIDER`
- `PAYMENTS_API_KEY`
- `PAYMENTS_WEBHOOK_SECRET`
- `WEBHOOK_BASE_URL`
- `WALLET_PROVIDER`
- `WALLET_PROJECT_ID`
- `WALLET_API_KEY`
@@ -74,8 +112,14 @@ production.
- `POLYMARKET_CLOB_API_KEY`
- `POLYMARKET_CLOB_SECRET`
- `POLYMARKET_CLOB_PASSPHRASE`
- `RECONCILIATION_STORE`
- `ACCOUNTING_EXPORT_STORE`
- `RATE_LIMIT_STORE`
- `AUDIT_LOG_STORE`
- `MONITORING_DSN`
- `INCIDENT_WEBHOOK_URL`
- `ADMIN_ALERT_EMAIL`
- `CUSTOMER_SUPPORT_EMAIL`
- `LIVE_TRADING_ENABLED=true` only after final approval and end-to-end testing
Even when all variables are present, live order placement remains intentionally
@@ -97,12 +141,33 @@ Useful official docs:
## Final setup checklist
1. Choose and contract the KYC / eligibility provider.
2. Choose the deposit and withdrawal provider.
3. Choose the wallet or embedded-wallet provider and create a deposit wallet.
4. Derive or create Polymarket CLOB credentials for the approved signing flow.
5. Create durable append-only audit storage.
6. Add all environment variables in Vercel.
7. Run dry-runs against `/api/live` and verify audit events.
8. Complete legal review, terms, restricted jurisdiction rules, and support
procedures.
9. Only then set `LIVE_TRADING_ENABLED=true`.
2. Choose and contract the sanctions/watchlist and geo-IP/geofencing providers.
3. Choose the deposit and withdrawal provider.
4. Choose the wallet or embedded-wallet provider and create a deposit wallet.
5. Build production accounts: auth, sessions, password reset, sign-out, account
database, consent records, and portfolio history storage.
6. Derive or create Polymarket CLOB credentials for the approved signing flow.
7. Build the live order router with signing, submission, cancellation, fill
tracking, idempotency, rate limits, and stale-order protection.
8. Build continuous reconciliation for cash, open orders, fills, positions,
withdrawals, fees, and resolved markets.
9. Enforce every user permission and risk limit on the server, not only in the
browser.
10. Create durable append-only audit storage, statements, exports, monitoring,
alerting, and support procedures.
11. Complete legal review, terms, privacy policy, risk disclosures, restricted
jurisdiction rules, market category policy, and incident response plan.
12. Add all environment variables in Vercel.
13. Run dry-runs and test-wallet trades; verify webhooks, audit events,
reconciliation, and user withdrawal paths.
14. Only then set `LIVE_TRADING_ENABLED=true`.
## What still cannot be completed from code alone
- Legal approval and jurisdiction-specific advice.
- KYC/KYB, sanctions, payments, wallet, and support vendor contracts.
- Real provider API keys, webhook secrets, CLOB credentials, and deposit wallet
addresses.
- Bank, stablecoin, or payment settlement relationships.
- Production security review and incident-response ownership.
- Final decision to enable live trading.
+38
View File
@@ -1,10 +1,25 @@
const REQUIRED_ENV = [
["PRODUCTION_APP_URL", "Production app URL"],
["AUTH_PROVIDER", "Real account authentication provider"],
["DATABASE_URL", "Production account database"],
["SESSION_SECRET", "Session signing secret"],
["ENCRYPTION_KEY", "Encryption key for sensitive user settings"],
["KYC_PROVIDER", "KYC / eligibility provider"],
["KYC_API_KEY", "KYC provider API key"],
["KYC_WEBHOOK_SECRET", "KYC webhook secret"],
["SANCTIONS_PROVIDER", "Sanctions / watchlist screening provider"],
["SANCTIONS_API_KEY", "Sanctions provider API key"],
["GEOIP_PROVIDER", "Geo-IP / geofencing provider"],
["GEOIP_API_KEY", "Geo-IP provider API key"],
["RESTRICTED_JURISDICTIONS", "Restricted jurisdiction rules"],
["TERMS_VERSION", "Approved terms version"],
["PRIVACY_VERSION", "Approved privacy policy version"],
["RISK_DISCLOSURE_VERSION", "Approved risk disclosure version"],
["MARKET_POLICY_STORE", "Market eligibility and category policy store"],
["PAYMENTS_PROVIDER", "Deposit and withdrawal provider"],
["PAYMENTS_API_KEY", "Payments provider API key"],
["PAYMENTS_WEBHOOK_SECRET", "Payments webhook secret"],
["WEBHOOK_BASE_URL", "Public webhook base URL"],
["WALLET_PROVIDER", "Wallet or deposit-wallet provider"],
["WALLET_PROJECT_ID", "Wallet provider project ID"],
["WALLET_API_KEY", "Wallet provider API key"],
@@ -15,8 +30,30 @@ const REQUIRED_ENV = [
["POLYMARKET_CLOB_PASSPHRASE", "Polymarket CLOB passphrase"],
["SETTLEMENT_ASSET", "Settlement asset"],
["SETTLEMENT_CHAIN", "Settlement chain"],
["RECONCILIATION_STORE", "Balance, position, and fill reconciliation store"],
["ACCOUNTING_EXPORT_STORE", "Statements, tax, and accounting export store"],
["RATE_LIMIT_STORE", "Rate limit and abuse prevention store"],
["AUDIT_LOG_STORE", "Durable audit log store"],
["MONITORING_DSN", "Error and performance monitoring"],
["INCIDENT_WEBHOOK_URL", "Incident alert webhook"],
["ADMIN_ALERT_EMAIL", "Admin alert destination"],
["CUSTOMER_SUPPORT_EMAIL", "Customer support contact"],
];
const LAUNCH_REQUIREMENTS = [
["legal", "Terms, privacy policy, risk disclosures, and jurisdiction policy approved"],
["eligibility", "KYC/KYB, age, sanctions, watchlist, and location screening active"],
["market_policy", "Allowed market categories, restricted events, and manipulation rules defined"],
["auth", "Production accounts, sessions, password reset, MFA path, and sign-out implemented"],
["wallets", "User-controlled wallet/deposit-wallet signing and permission revocation implemented"],
["payments", "Deposits, withdrawals, webhooks, failed-payment handling, and support flows implemented"],
["execution", "Signed order creation, CLOB submission, cancellation, retry, and fill tracking implemented"],
["reconciliation", "Cash, open orders, positions, fills, fees, and withdrawals reconciled continuously"],
["risk", "Agent allocation caps, market caps, stop rules, manual approval, and emergency pause enforced server-side"],
["security", "Secret management, encryption, rate limits, abuse controls, and security review completed"],
["records", "Append-only audit logs, customer statements, exports, and retention policy active"],
["operations", "Monitoring, incident response, customer support, and rollback plan ready"],
["testing", "Paper-to-live parity, dry-runs, test wallets, webhook tests, and edge-case QA completed"],
];
function providerStatus() {
@@ -55,6 +92,7 @@ function baseStatus() {
? null
: "Live trading is locked until eligibility, payments, wallet/deposit-wallet signing, Polymarket CLOB credentials, audit storage, monitoring, and LIVE_TRADING_ENABLED=true are configured.",
providers,
launch_requirements: LAUNCH_REQUIREMENTS.map(([key, label]) => ({ key, label })),
next_required: missing,
docs: {
polymarket_overview: "https://docs.polymarket.com/trading/overview",
+21 -13
View File
@@ -615,9 +615,11 @@ footer{margin-top:34px;padding-top:22px;border-top:1px solid var(--border);color
<ol class="steps">
<li><b>Eligibility</b> — identity checks, location restrictions, age checks, terms acceptance, and sanctions screening.</li>
<li><b>Wallets</b> — non-custodial wallet connection or Polymarket deposit-wallet flow so users sign orders themselves.</li>
<li><b>Funds</b>compliant deposit/withdraw rails, reconciled balances, statements, tax/accounting exports, and customer support.</li>
<li><b>Execution</b>order router using Polymarket CLOB authentication, signed orders, cancellations, fill tracking, and audit logs.</li>
<li><b>Risk controls</b> — user permissions for each agent, exposure limits, stop rules, emergency pause, and withdrawal access at all times.</li>
<li><b>Accounts</b>production login, sign-out, password reset, consent records, portfolio history, and secure sessions.</li>
<li><b>Funds</b>compliant deposit/withdraw rails, webhooks, reconciled balances, statements, tax/accounting exports, and customer support.</li>
<li><b>Execution</b> — order router using Polymarket CLOB authentication, signed orders, cancellations, fill tracking, idempotency, retries, and stale-order protection.</li>
<li><b>Risk controls</b> — server-side user permissions for each agent, exposure limits, stop rules, emergency pause, market blacklists, and withdrawal access at all times.</li>
<li><b>Operations</b> — monitoring, alerts, security review, audit retention, incident response, and rollback plan.</li>
</ol>
</div>
<div class="disclaimer">⚠️ <b>Paper trading only — not financial advice.</b> Nothing here places real orders or moves money. The analysis is a transparent heuristic. Portfolios sync through the site when cloud state is available, with this browser keeping a local backup.</div>
@@ -2217,14 +2219,19 @@ function renderAbout(){
<div class="fic">${a.emoji}</div><h4>${a.name}</h4><p>${agentBlurb(a,st)}</p></div>`).join("");
}
const LIVE_CHECKS=[
["eligibility","KYC / eligibility provider selected"],
["jurisdiction","Jurisdiction rules and geoblocking defined"],
["wallet","Wallet or deposit-wallet connection designed"],
["payments","Deposit and withdrawal provider selected"],
["clob","Polymarket CLOB order router backend planned"],
["audit","Immutable audit log for signals, orders, fills, and withdrawals"],
["risk","User risk limits and emergency pause controls"],
["legal","Legal review and terms approved"],
["legal","Terms, privacy policy, risk disclosures, and jurisdiction policy approved"],
["eligibility","KYC/KYB, age, sanctions, watchlist, and location screening active"],
["market_policy","Allowed market categories, restricted events, and manipulation rules defined"],
["auth","Production accounts, sessions, password reset, MFA path, and sign-out implemented"],
["wallet","User-controlled wallet/deposit-wallet signing and permission revocation implemented"],
["payments","Deposits, withdrawals, webhooks, failed-payment handling, and support flows implemented"],
["clob","Signed order creation, CLOB submission, cancellation, retry, and fill tracking implemented"],
["reconciliation","Cash, open orders, positions, fills, fees, and withdrawals reconciled continuously"],
["risk","Agent allocation caps, market caps, stop rules, manual approval, and emergency pause enforced server-side"],
["security","Secret management, encryption, rate limits, abuse controls, and security review completed"],
["records","Append-only audit logs, customer statements, exports, and retention policy active"],
["operations","Monitoring, incident response, customer support, and rollback plan ready"],
["testing","Paper-to-live parity, dry-runs, test wallets, webhook tests, and edge-case QA completed"],
];
function defaultLiveState(){
const checks={};LIVE_CHECKS.forEach(([k])=>checks[k]=false);
@@ -2260,8 +2267,9 @@ function renderLiveBackendStatus(){
const s=LIVE_BACKEND_STATUS;
if(!s){root.innerHTML="Checking backend readiness...";return;}
const providers=(s.providers||[]).map(p=>`<div class="leader-row"><span>${esc(p.label)}${p.expected?`<div class="small muted">${esc(p.expected)}</div>`:""}</span><b class="${p.configured?"pos-val":"neg-val"}">${p.configured?"configured":"missing"}</b></div>`).join("");
const next=(s.next_required||[]).slice(0,8).map(x=>`<li>${esc(x)}</li>`).join("");
root.innerHTML=`<b>${s.live_trading_enabled?"Live trading unlocked":"Live trading locked"}</b><div class="small muted" style="margin:6px 0">${esc(s.locked_reason||"All required backend providers are configured.")}</div>${providers}${next?`<div class="locked-panel" style="margin-top:10px"><b>Next setup items</b><ul>${next}</ul></div>`:""}<div class="small muted" style="margin-top:8px">Live execution stays disabled until every provider is configured and final approval flips LIVE_TRADING_ENABLED=true.</div>`;
const next=(s.next_required||[]).slice(0,12).map(x=>`<li>${esc(x)}</li>`).join("");
const reqs=(s.launch_requirements||[]).map(x=>`<li>${esc(x.label)}</li>`).join("");
root.innerHTML=`<b>${s.live_trading_enabled?"Live trading unlocked":"Live trading locked"}</b><div class="small muted" style="margin:6px 0">${esc(s.locked_reason||"All required backend providers are configured.")}</div>${providers}${next?`<div class="locked-panel" style="margin-top:10px"><b>Next setup items</b><ul>${next}</ul></div>`:""}${reqs?`<div class="locked-panel" style="margin-top:10px"><b>Full launch requirements</b><ol>${reqs}</ol></div>`:""}<div class="small muted" style="margin-top:8px">Live execution stays disabled until every provider is configured, every launch requirement is complete, and final approval flips LIVE_TRADING_ENABLED=true.</div>`;
}
async function dryRunLiveOrderIntent(){
const s=loadLiveState();