Skip to main content

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

FieldTypeRequiredValidation
exchange_platformselectYesMust be valid platform
actionselectYesMust be buy or sell
cryptocurrencyselectYesMust be supported by platform
fiat_currencyselectYesMust be supported
amountnumberYesMust be > 0
order_typeselectYesMust be market or limit
price_limit_usdnumberConditionalRequired if order_type=limit, must be > 0
integration_account_idtextYesMust be valid UUID
max_single_order_usdnumberNoMust be > 0 if set
max_daily_volume_usdnumberNoMust 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 * and aria-required="true"
  • ✅ Conditional fields have aria-hidden when not applicable
  • ✅ Helper text provides context via aria-describedby
  • ✅ Select dropdowns use native HTML <select>
  • ✅ Numeric inputs use type="number" with appropriate step

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