dev.cds-mobile

作成者: coinbase

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

coinbaseのその他のスキル

git.repo-manager
coinbase
git.repo-manager — coinbase/cds が公開する、AIエージェント向けのインストール可能なスキルです。
official
agentic-wallet
coinbase
awal CLIによる暗号ウォレット操作 — サインイン、残高確認、USDC/ETH/POL/SOLの送金、トークン取引、ウォレットへの資金追加、x402支払いプロトコルの使用…
official
authenticate-wallet
coinbase
メールOTPベースのウォレット認証、検証、ステータス確認機能。2段階ログインフロー:メールで6桁のOTPを受信し、flowIdとコードで検証して認証を完了。コマンド実行前にシェルインジェクションを防ぐため、メール、flowId、OTPの入力検証ルールを実装。ステータス確認、残高照会、アドレス取得、ウォレットウィンドウアクセスをCLIコマンドで提供。全コマンドは機械可読な--json出力に対応。
official
fund
coinbase
Coinbase Onrampまたは直接送金でウォレットにUSDCを入金します。ユーザーがプリセット金額($10、$20、$50)またはカスタム値を選択し、Apple Pay、デビットカード、銀行振込、Coinbaseアカウントからの資金調達方法を選べる補助UIを開きます。カードとApple Payは即時、ACH銀行振込は1~3日と、決済時間が異なる複数の支払い方法に対応しています。Baseネットワーク上でUSDCとして資金を入金します。また、npx awal@2.0.3...経由でウォレットアドレスに直接USDCを送金することもできます。
official
monetize-service
coinbase
有料APIエンドポイントをデプロイし、他のエージェントがx402プロトコルを介して発見・支払いできるようにします。HTTP 402支払いプロトコルを使用してBase上でリクエストごとにUSDCを請求。クライアントは署名済みトランザクションで支払い、APIキーやアカウントは不要。ディスカバリー拡張を宣言すると、エンドポイントが自動的にx402 Bazaarに登録され、エージェントによる発見が可能に。Expressミドルウェアを使用して、エンドポイントごとに複数の価格帯、ワイルドカードルート、複数の支払いオプションをサポート。@x402/expressおよび@x402/core上に構築...
official
pay-for-service
coinbase
Base上でx402プロトコルを介した自動USDC支払いにより有料APIを呼び出します。x402対応エンドポイントに対してHTTPリクエスト(GET、POSTなど)を実行し、USDC支払いを自動的に処理します。メソッド、JSONボディ、クエリパラメータ、カスタムヘッダーを通じたリクエストのカスタマイズをサポートします。支払い制御機能を含みます:リクエストごとの最大USDC金額の設定、相関IDによる関連操作のグループ化。ウォレット認証と十分なUSDC残高が必要です。シェルインジェクションを防ぐため、すべてのユーザー入力を検証します...
official
query-blockchain-data
coinbase
BaseのCDP SQL APIを介してx402を使用し、オンチェーンのブロックチェーンデータをクエリします。あなたまたはユーザーがデコードされたブロックに関するオンチェーン情報を確認したい場合に使用します。
official
query-onchain-data
coinbase
Base上のオンチェーンデータをSQLでクエリし、クエリごとにx402支払いを行います。CoinbaseQL(ClickHouseベースのSQL方言)を介して、デコードされたイベント、トランザクション、ブロックにアクセス可能。結合、CTE、サブクエリ、標準関数をサポート。利用可能な3つの主要テーブル:base.events(デコードされたスマートコントラクトログ)、base.transactions(完全なトランザクションデータ)、base.blocks(ブロックメタデータ)。イベントクエリでは、インデックス付きフィールド(event_signature、address、block_timestamp)でのフィルタリングが必要で、全テーブルスキャンを回避します。
official