Crypto Buy/Sell Module - Form Configuration Guide
Form Fields Generated from Module Definition
The ExecModuleConfigBuilder automatically generates UI form fields from the execModuleCatalog.ts module definition.
Basic Form (Core Fields)
┌──────────────────────────────────────── ─┐
│ Crypto Buy/Sell Configuration │
├─────────────────────────────────────────┤
│ │
│ Exchange Platform * │
│ ┌─────────────────────────────────┐ │
│ │ Coinbase ▼ │ │
│ └─────────────────────────────────┘ │
│ Options: Coinbase, Coinbase Sandbox, │
│ Kraken, Binance │
│ │
│ Action * │
│ ┌─────────────────────────────────┐ │
│ │ Buy ▼ │ │
│ └─────────────────────────────────┘ │
│ Options: Buy, Sell │
│ │
│ Cryptocurrency * │
│ ┌─────────────────────────────────┐ │
│ │ BTC ▼ │ │
│ └─────────────────────────────────┘ │
│ Options: BTC, ETH, USDC, USDT, SOL, ADA
│ │
│ Fiat Currency * │
│ ┌─────────────────────────────────┐ │
│ │ USD ▼ │ │
│ └─────────────────────────────────┘ │
│ Options: USD, EUR, GBP │
│ │
│ Amount * │
│ ┌─────────────────────────────────┐ │
│ │ 0.5 │ │
│ └─────────────────────────────────┘ │
│ │
│ Order Type * │
│ ┌─────────────────────────────────┐ │
│ │ Market ▼ │ │
│ └─────────────────────────────────┘ │
│ Options: Market (immediate), │
│ Limit (price-based) │
│ │
│ Integration Account ID * │
│ ┌─────────────────────────────────┐ │
│ │ [Integration Account Lookup] │ │
│ └─────────────────────────────────┘ │
│ (ApiLookupField with QBE search) │
│ │
└─────────────────────────────────────────┘
Advanced Form (Optional Fields)
┌─────────────────────────────────────────┐
│ Advanced Options (Collapsible) │
├─────────────────────────────────────────┤
│ │
│ Price Limit USD │
│ ┌─────────────────────────────────┐ │
│ │ 45000.00 │ │
│ └─────────────────────────────────┘ │
│ (Only visible when Order Type = Limit) │
│ │
│ Time In Force │
│ ┌─────────────────────────────────┐ │
│ │ Immediate ▼ │ │
│ └─────────────────────────────────┘ │
│ Options: Immediate, Post Only, │
│ Fill or Kill │
│ │
│ Auto Convert │
│ ☐ Convert stablecoins automatically │
│ │
│ Webhook URL │
│ ┌─────────────────────────────────┐ │
│ │ https://webhook.example.com/... │ │
│ └─────────────────────────────────┘ │
│ │
└─────────────────────────────────────────┘
Risk Controls Form (Accordion)
┌─────────────────────────────────────────┐
│ Risk Controls ▼ │
├─────────────────────────────────────────┤
│ │
│ ☑ Enable Velocity Checks │
│ │
│ Max Single Order (USD) │
│ ┌─────────────────────────────────┐ │
│ │ 25000 │ │
│ └─────────────────────────────────┘ │
│ (Fails order if exceeded) │
│ │
│ Max Daily Volume (USD) │
│ ┌─────────────────────────────────┐ │
│ │ 100000 │ │
│ └─────────────────────────────────┘ │
│ (Fails order if daily total exceeded) │
│ │
└─────────────────────────────────────────┘
Notifications Form (Accordion)
┌─────────────────────────────────────────┐
│ Notifications ▼ │
├─────────────────────────────────────────┤
│ │
│ ☑ On Fill │
│ ☐ On Partial Fill │
│ ☑ On Cancel │
│ │
│ Webhook URL (for callbacks) │
│ ┌─────────────────────────────────┐ │
│ │ https://webhook.example.com/... │ │
│ └─────────────────────────────────┘ │
│ │
└─────────────────────────────────────────┘
Dynamic Form Behavior
Conditional Visibility
Price Limit Field:
- ✓ Visible when
Order Type = "limit" - ✗ Hidden when
Order Type = "market" - ✓ Mark as required when visible
Time In Force Field:
- ✓ Visible when
Order Type = "limit" - ✗ Disabled when
Order Type = "market"
Field Validation
| Field | Type | Required | Validation |
|---|---|---|---|
| exchange_platform | select | Yes | Must be valid platform |
| action | select | Yes | Must be buy or sell |
| cryptocurrency | select | Yes | Must be supported by platform |
| fiat_currency | select | Yes | Must be supported |
| amount | number | Yes | Must be > 0 |
| order_type | select | Yes | Must be market or limit |
| price_limit_usd | number | Conditional | Required if order_type=limit, must be > 0 |
| integration_account_id | text | Yes | Must be valid UUID |
| max_single_order_usd | number | No | Must be > 0 if set |
| max_daily_volume_usd | number | No | Must be >= max_single_order_usd if set |
Form State Management
// Redux state
{
modules: {
activeModuleConfig: {
moduleType: "payment.crypto.buy_sell",
exchange_platform: "coinbase",
action: "buy",
cryptocurrency: "BTC",
fiat_currency: "USD",
amount: 0.5,
order_type: "market",
integration_account_id: "uuid-123",
price_limit_usd: null, // Hidden
risk_controls: {
velocity_check: true,
max_single_order_usd: 25000,
max_daily_volume_usd: 100000
},
notifications: {
on_fill: true,
on_partial_fill: false,
on_cancel: true
}
}
}
}
Integration Account Lookup
Field Type: apiLookup
{
fieldType: "apiLookup",
name: "integration_account_id",
label: "Integration Account",
required: true,
apiService: "IntegrationAccountService",
apiMethod: "getIntegrationAccounts",
displayField: "name",
valueField: "id",
filterExample: {
provider: "coinbase", // or "kraken", "binance"
status: "active"
},
helperText: "Select an Integration Account with Crypto Exchange credentials"
}
QBE Filter Applied:
{
"example": {
"provider": "{{currentExchange}}",
"status": "active"
}
}
Form Submission & Validation
Pre-Submit Validation
validateFormSubmission(moduleData) {
// Check required fields
if (!moduleData.exchange_platform) throw "Exchange platform required";
if (!moduleData.action) throw "Action required";
if (!moduleData.cryptocurrency) throw "Cryptocurrency required";
if (!moduleData.amount || moduleData.amount <= 0) throw "Valid amount required";
// Conditional validation
if (moduleData.order_type === "limit") {
if (!moduleData.price_limit_usd || moduleData.price_limit_usd <= 0) {
throw "Price limit required for limit orders";
}
}
// Risk control validation
if (moduleData.risk_controls) {
const single = moduleData.risk_controls.max_single_order_usd;
const daily = moduleData.risk_controls.max_daily_volume_usd;
if (single && daily && single > daily) {
throw "Single order max cannot exceed daily volume max";
}
}
}
Payload Structure
Submitted to Backend:
{
moduleType: "payment.crypto.buy_sell",
moduleData: JSON.stringify({
exchange_platform: "coinbase",
action: "buy",
cryptocurrency: "BTC",
fiat_currency: "USD",
amount: 0.5,
order_type: "market",
integration_account_id: "550e8400-e29b-41d4-a716-446655440000",
idempotency_key: "crypto_{{requestId}}",
risk_controls: {
velocity_check: true,
max_daily_volume_usd: 100000,
max_single_order_usd: 25000
},
notifications: {
on_fill: true,
on_partial_fill: false,
on_cancel: true
}
})
}
UI/UX Patterns
Default Values
exchange_platform: "coinbase" (user-friendly)action: "buy" (common operation)cryptocurrency: "BTC" (most popular)fiat_currency: "USD" (default for US users)order_type: "market" (immediate execution)risk_controls.velocity_check: true (safe default)
Preset Configurations
Market Order Preset:
Order Type: Market
Price Limit: Hidden
Time In Force: Immediate (disabled)
Limit Order Preset:
Order Type: Limit
Price Limit: Visible & Required
Time In Force: Visible (default Immediate)
Error Display
Form-level errors:
Integration Account not found: [ID]
Please select a valid Integration Account with active credentials.
Field-level errors:
Amount: Must be greater than 0
Price Limit USD: Required for limit orders
Max Single Order: Cannot exceed daily volume maximum
Accessibility
- ✅ All inputs labeled with
<label>elements - ✅ Required fields marked with
*andaria-required="true" - ✅ Conditional fields have
aria-hiddenwhen not applicable - ✅ Helper text provides context via
aria-describedby - ✅ Select dropdowns use native HTML
<select> - ✅ Numeric inputs use
type="number"with appropriatestep
Mobile Responsiveness
- ✅ Single column layout on mobile
- ✅ Full-width inputs and dropdowns
- ✅ Collapsible sections for advanced options
- ✅ Touch-friendly button sizes (48px minimum)
- ✅ Platform picker uses native select on mobile
Internationalization (i18n)
{
en: {
"crypto.exchange_platform": "Exchange Platform",
"crypto.exchange_platform.helper": "Select cryptocurrency exchange",
"crypto.action": "Action",
"crypto.action.buy": "Buy",
"crypto.action.sell": "Sell",
// ... more keys
},
es: {
"crypto.exchange_platform": "Plataforma de Cambio",
// ... spanish translations
}
}
Next: See CRYPTO_BUYSELL_MODULE.md for API configuration details