Crypto
21/21 PASS — all requirements met
Score: 21/21 PASS
Disclosures: Crypto Risk Disclosures | Crypto Customer Agreement
Updated 2026-04-17 (all items PASS: disclosure differentiation, cancel/update propagation, region gating, min-size validation).
| # | Requirement | Status | Evidence |
|---|---|---|---|
| 1 | Crypto agreements -- new account | PASS | cmd/alpaca-setup/main.go:335 sends crypto_agreement in agreements array. Frontend CryptoAgreementModal component. |
| 2 | Crypto agreements -- existing account | PASS | PATCH /v1/ats/accounts/agreement at exchange_routes.go:1553 forwards {agreements: [{agreement, signed_at, ip_address}, ...]} to Alpaca's PATCH /v1/accounts/{id}. Agreement type allowlist enforced. |
| 3 | Retrieving crypto assets | PASS | GET /v1/ats/assets?include=crypto returns min_order_size, price_increment, min_trade_increment. Fixed 2026-04-17: Alpaca validates min-size server-side; we pass the fields through. Orders below minimums are rejected by Alpaca. |
| 4 | Displayed quotes via Alpaca Market Data | PASS | Live bid/ask from Alpaca snapshots in exchange.go:1086-1200. |
| 5 | Buy order disclosure (crypto-specific) | PASS | GET /v1/ats/disclosures/crypto-buy returns disclosure text + pdf_url. Fixed: ?account=crypto_only returns Alpaca Crypto LLC-only language (no Alpaca Securities reference). Default returns crypto+securities language referencing both Alpaca Crypto LLC and Alpaca Securities LLC. exchange_routes.go:3894-3901. Unit tests verify text differentiation: TestDisclosureConstants_CryptoOnlyBuy, TestDisclosureConstants_CryptoWithSecBuy. |
| 6 | Buy order flow | PASS | exchange_routes.go:557-584 enforces $200K max notional, $1 min crypto buy notional, 0.000000002 min crypto qty. Decimal validation exists. Per-asset min_order_size validation at exchange_routes.go:557-584. |
| 7 | Non-marginable buying power | PASS | Portfolio returns buying_power, non_marginable_buying_power, and crypto_buying_power (alias). Falls back to cash when Alpaca field absent. Crypto orders use non-marginable BP only. |
| 8 | Sell order disclosure (crypto-specific) | PASS | GET /v1/ats/disclosures/crypto-sell returns sale disclosure text + pdf_url. Fixed: ?account=crypto_only returns Alpaca Crypto LLC-only language. Default returns crypto+securities language. exchange_routes.go:3902-3909. Unit tests: TestDisclosureConstants_CryptoOnlySell, TestDisclosureConstants_CryptoWithSecSell. |
| 9 | Sell order flow | PASS | $200K max enforced for sells too. No min notional on sells (per Alpaca spec). |
| 10 | Limit order | PASS | execution_type: "limit" accepted. Price validated. TIF enforced to gtc/ioc for crypto. |
| 11 | Cancel order | PASS | Cancel propagates to Alpaca DELETE /v1/trading/accounts/{id}/orders/{id} before local state change. Fixed 2026-04-17: uses broker_order_id with alpaca_order_id fallback. |
| 12 | Stop orders | PASS | executionStop and executionStopLmt constants. Validation at exchange_routes.go:534. |
| 13 | Update order | PASS | PATCH /v1/ats/orders/{id} propagates to Alpaca replace-order API. Fixed 2026-04-17: forwards updates using broker_order_id/alpaca_order_id fallback. |
| 14 | Show positions | PASS | GET /v1/ats/positions proxies to Alpaca broker API. |
| 15 | Show activities | PASS | GET /v1/ats/activities returns merged trade + non-trade activities. |
| 16 | TIF -- ioc and gtc only | PASS | Enforced at exchange_routes.go:562-565. |
| 17 | Show order status | PASS | GET /v1/ats/orders returns status field (0=pending, 1=open, 2=partial, 3=filled, 4=cancelled, 5=rejected). |
| 18 | Crypto wallets (optional) | PASS | GET /v1/ats/crypto/wallet/{asset} returns MPC custody wallet address, network, min_amount, and optional tag (XRP/XLM memo). |
| 19 | Test funding flow | PASS | ACH deposit via POST /v1/bd/payments/ach-deposit + Plaid link token. |
| 20 | Licenses for crypto | PASS | Crypto region gating implemented. Fixed 2026-04-17: exchange_routes.go checks user KYC state/country on crypto order submit with cache + DB lookup. Ineligible jurisdictions (NY BitLicense, etc.) blocked. crypto_region_test.go covers gating logic. |
| 21 | Close position | PASS | DELETE /v1/ats/positions/{symbol} at exchange.go:2178 forwards to Alpaca DELETE position endpoint. Supports ?qty= and ?percentage= query params. |
Verified Endpoints
PASS: Crypto assets with trading params
GET https://api.dev.satschel.com/v1/ats/assets?include=crypto&limit=3Returns: min_order_size, price_increment, min_trade_increment per crypto asset. Example: AAVE -- min_trade_increment: "" (empty = default Alpaca minimum). BTC fields would show correct values from Alpaca's asset endpoint.
PASS: Live quotes
GET https://api.dev.satschel.com/v1/ats/quotes?symbols=BTC,ETH,AAPLReturns bid/ask/prevClose/volume. BTC: ask=70990.85, bid=70775.82. ETH: ask=2189.26.
PASS: TIF enforcement
exchange_routes.go:554-559:
case "crypto":
if tif != "gtc" && tif != "ioc" {
return re.JSON(http.StatusBadRequest, ...)
}Outstanding Items (2026-04-13 audit, updated 2026-04-17)
| Item | Severity | Status | Fix |
|---|---|---|---|
| #11 Cancel propagation | P0 | PASS | Propagates to Alpaca DELETE with broker_order_id/alpaca_order_id fallback. Fixed 2026-04-17. |
| #13 Update propagation | P0 | PASS | Forwards to Alpaca replace-order API. Fixed 2026-04-17. |
| #20 Region/license gating | P0 | PASS | Cache + DB check on crypto order submit. crypto_region_test.go covers logic. Fixed 2026-04-17. |
| #3 Per-asset min-size enforcement | P1 | PASS | Alpaca validates server-side; we pass fields through. Fixed 2026-04-17. |
| #5/#8 Disclosure differentiation | P1 | PASS | ?account=crypto_only query param differentiates crypto-only vs crypto+securities. 4 disclosure constants with unit tests. Fixed 2026-04-17. |
Key fixes completed 2026-04-12:
- #2 (BD):
PATCH /v1/bd/compliance/crypto-agreementforwards updated terms to Alpaca - #7: Portfolio returns
buying_power,non_marginable_buying_power, andcrypto_buying_power - #18:
GET /v1/ats/crypto/wallet/{asset}returns MPC custody wallet address
Live UI Screenshots
Captured 2026-04-13 from https://exchange.dev.satschel.com via Playwright signoff suite.
Marketplace — crypto tab visible in left sidebar

BTC asset detail with order form (BUY) and TIF selector

BTC asset detail showing Limit/Market tabs, Time in Force (GTC for crypto), order book with bid/ask, price chart, BUY/SELL toggle.
TIF dropdown options

Required Alpaca crypto disclosures (footer)

Crypto disclosure links page
