dev.cds-mobile

USE THIS when asked to work on a new or existing (MOBILE) CDS React component in packages/mobile

npx skills add https://github.com/coinbase/cds --skill dev.cds-mobile

CDS Mobile Package Guidelines

Mobile-specific patterns for @coinbase/cds-mobile.

Component Config Adoption (Mobile)

Use this guidance when adding ComponentConfigProvider defaults for the specific component you are editing.

Required implementation pattern

  1. Register the component in packages/mobile/src/core/componentConfig.ts using its *BaseProps:
import type { MyComponentBaseProps } from '../category/MyComponent';

export type ComponentConfig = {
  MyComponent?: ConfigResolver<MyComponentBaseProps>;
};
  1. Adopt useComponentConfig in the component and destructure from merged props:
import { useComponentConfig } from '../hooks/useComponentConfig';

export const MyComponent = memo((_props: MyComponentProps) => {
  const mergedProps = useComponentConfig('MyComponent', _props);
  const { style, ...props } = mergedProps;

  return <Pressable style={style} {...props} />;
});

Rules to preserve behavior

  • Provider config supplies defaults only; local props must continue to win.
  • Use _props as the input variable and mergedProps as the configured output.
  • Type resolver entries with *BaseProps (not full *Props).
  • Keep scope to prop-level theming defaults; do not alter component behavior or control flow.
  • When practical during the same change, prefer arrow-function component declarations.

Styling with StyleSheet

Use StyleSheet.create for static styles and useTheme() for dynamic values:

import { StyleSheet, type StyleProp, type ViewStyle } from 'react-native';

const styles = StyleSheet.create({
  container: { position: 'relative', width: '100%' },
});

// Dynamic styles via theme hook
const theme = useTheme();
const dynamicStyle = {
  backgroundColor: theme.color.bgPrimary,
  padding: theme.space[2],
};

<View style={[styles.container, dynamicStyle, style]} />;

Inline styles

  • Mobile components should all expose a style and styles object props for overriding default styles.
  • As styling is a concern of that specific component, the style and styles props should never be on the *BaseProps type.
  • styles can be used for granular overrides on child elements within the component.
  • Always merge styles into a react-native style array with useMemo in the correct order (default styles => style prop => styles[ELEMENT_NAME] prop).

Example:

type ComponentProps = ComponentBaseProps & {
  style?: StyleProp<ViewStyle>;
  styles?: {
    root?: StyleProp<ViewStyle>;
    label?: StyleProp<TextStyle>;
  };
};

const theme = useTheme();
const containerStyles = useMemo(
  () => [
    { backgroundColor: theme.color.bgPrimary }, // default styles
    style, // from props
    styles.root, // from props
  ],
  [theme.color.bgPrimary, animatedStyles, style]
);

// Apply to component
<Box style={containerStyles}>

Animation

React Native Reanimated

import Animated, { useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';

const opacity = useSharedValue(0);
const animatedStyle = useAnimatedStyle(() => ({
  opacity: opacity.value,
  transform: [{ translateY: withTiming(opacity.value * -8) }],
}));

<Animated.View style={animatedStyle} />;

We DO NOT use React-Spring anymore for animations on mobile.

Gesture Handling

Use react-native-gesture-handler:

import { Gesture, GestureDetector } from 'react-native-gesture-handler';

const panGesture = useMemo(
  () =>
    Gesture.Pan()
      .onStart(() => {
        /* ... */
      })
      .onUpdate(({ translationX }) => {
        /* ... */
      })
      .onEnd(({ translationX, velocityX }) => {
        /* ... */
      })
      .withTestId(testID)
      .runOnJS(true),
  [dependencies],
);

<GestureDetector gesture={panGesture}>
  <Animated.View>{/* ... */}</Animated.View>
</GestureDetector>;

Layout Measurement

Use onLayout callback instead of ResizeObserver:

const [size, onLayout] = useLayout();
<View onLayout={onLayout} />

// Or inline
<View onLayout={(e) => setHeight(e.nativeEvent.layout.height)} />

Accessibility

  • Use appropriate accessibilityLabel, accessibilityHint, and accessibilityRole, accessibilityState props
  • Support screen readers (VoiceOver and TalkBack)
  • Ensure touch targets meet minimum size requirements (44x44 points)

Example: Use React Native accessibility props:

<View
  accessible
  accessibilityRole="adjustable"
  accessibilityLabel="Product carousel"
  accessibilityLiveRegion="polite"
>
  <Pressable
    accessibilityState={{ selected: isActive, disabled }}
    accessibilityActions={[{ name: 'activate' }]}
    onAccessibilityAction={handleAccessibilityAction}
  />
</View>

Screen Reader Content

// Hide visual content from screen readers
<View accessibilityElementsHidden importantForAccessibility="no-hide-descendants">
  {/* Animated/visual content */}
</View>

// Provide accessible alternative
<Text
  importantForAccessibility="yes"
  accessibilityLiveRegion="polite"
  style={{ color: 'transparent', position: 'absolute' }}
>
  {accessibleLabel}
</Text>

Reference Components

  • SlideButton: gesture handling, spring animations, accessibility actions
  • RollingNumber: Reanimated, measurement patterns, screen reader content
  • Select (alpha/): controlled/uncontrolled, Drawer integration
  • Stepper: direction-based defaults, shared logic from cds-common
  • Tour: animations, complexity
  • DatePicker: complexity

Más skills de coinbase

git.repo-manager
coinbase
git.repo-manager — una habilidad instalable para agentes de IA, publicada por coinbase/cds.
official
agentic-wallet
coinbase
Operaciones de billetera cripto a través de la CLI awal: iniciar sesión, consultar saldos, enviar USDC/ETH/POL/SOL, intercambiar tokens, fondear la billetera y usar el protocolo de pago x402 para…
official
authenticate-wallet
coinbase
Autenticación de cartera basada en OTP por correo electrónico con validación y verificación de estado. Flujo de inicio de sesión en dos pasos: iniciar con correo electrónico para recibir un OTP de 6 dígitos, luego verificar con el flowId y código para completar la autenticación. Incluye reglas de validación de entrada para correo electrónico, flowId y OTP para prevenir inyección de shell antes de ejecutar comandos. Proporciona verificación de estado, consultas de saldo, recuperación de direcciones y acceso a la ventana de cartera a través de comandos CLI complementarios. Todos los comandos admiten salida --json para formato legible por máquina...
official
fund
coinbase
Depositar USDC a la billetera a través de Coinbase Onramp o transferencia directa. Abre una interfaz de usuario complementaria donde los usuarios seleccionan montos preestablecidos ($10, $20, $50) o valores personalizados y eligen entre Apple Pay, tarjeta de débito, transferencia bancaria o financiación de cuenta Coinbase. Admite múltiples métodos de pago con diferentes tiempos de liquidación: instantáneo para tarjeta y Apple Pay, de 1 a 3 días para transferencias bancarias ACH. Deposita fondos como USDC en la red Base; alternativamente, los usuarios pueden enviar USDC directamente a la dirección de la billetera a través de npx awal@2.0.3...
official
monetize-service
coinbase
Implementa un endpoint de API de pago que otros agentes puedan descubrir y pagar mediante el protocolo x402. Cobra USDC por solicitud en Base usando el protocolo de pago HTTP 402; los clientes pagan con transacciones firmadas, sin necesidad de claves API ni cuentas. Registra automáticamente los endpoints en el Bazaar x402 para el descubrimiento de agentes cuando declaras extensiones de descubrimiento. Soporta múltiples niveles de precios, rutas comodín y múltiples opciones de pago por endpoint usando middleware de Express. Construido sobre @x402/express y @x402/core...
official
pay-for-service
coinbase
Llama a APIs de pago en Base con pago automático en USDC mediante el protocolo x402. Ejecuta solicitudes HTTP (GET, POST, etc.) a endpoints habilitados para x402 con pagos atómicos en USDC gestionados automáticamente. Admite personalización de solicitudes a través del método, cuerpo JSON, parámetros de consulta y encabezados personalizados. Incluye controles de pago: establece el monto máximo de USDC por solicitud y agrupa operaciones relacionadas con IDs de correlación. Requiere autenticación de billetera y saldo suficiente de USDC; valida toda la entrada del usuario para prevenir shell...
official
query-blockchain-data
coinbase
Consulta datos onchain de blockchain en Base usando la API SQL de CDP a través de x402. Úsalo cuando tú o tu usuario quieran ver información onchain sobre bloques decodificados,…
official
query-onchain-data
coinbase
Consulta datos on-chain en Base usando SQL con pagos x402 por consulta. Accede a eventos decodificados, transacciones y bloques a través de CoinbaseQL, un dialecto SQL basado en ClickHouse que soporta joins, CTEs, subconsultas y funciones estándar. Tres tablas principales disponibles: base.events (logs de contratos inteligentes decodificados), base.transactions (datos completos de transacciones) y base.blocks (metadatos de bloques). Requiere filtrar por campos indexados (event_signature, address, block_timestamp) en consultas de eventos para evitar escaneos completos de tabla...
official