OnePairSelector
The OnePairSelector component renders a selectable list of trading pairs, filtered by strategy and chain. Each pair is displayed with its icon (via PAIR_ICONS), symbol, and order size constraints.
React Native Only
OnePairSelector is exported from the React Native entry point of @one_deploy/sdk. It is not available on web.
Quick Start
import { useState } from 'react';
import { OnePairSelector } from '@one_deploy/sdk';
import type { TradingPair } from '@one_deploy/sdk';
function PairStep() {
const [selectedPair, setSelectedPair] = useState<TradingPair | null>(null);
return (
<OnePairSelector
strategyId="strat_abc123"
chainId={8453}
onSelect={(pair) => {
setSelectedPair(pair);
console.log('Selected:', pair.symbol);
}}
/>
);
}
OnePairSelectorProps
interface OnePairSelectorProps {
/** Strategy ID to filter pairs by the strategy's supported pairs. */
strategyId: string;
/** Chain ID to filter pairs available on this network. */
chainId: number;
/** Currently selected pair symbol. */
selectedPair?: string;
/** Callback fired when the user selects a pair. */
onSelect: (pair: TradingPair) => void;
/** Whether to show pair icons from PAIR_ICONS. Defaults to true. */
showIcons?: boolean;
/** Whether to show inactive pairs (greyed out, not selectable). Defaults to false. */
showInactive?: boolean;
/** Additional style applied to the container. */
style?: ViewStyle;
/** Style applied to each pair item. */
itemStyle?: ViewStyle;
/** Test ID for testing frameworks. */
testID?: string;
}
Props Table
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
strategyId | string | Yes | -- | Strategy ID to filter supported pairs |
chainId | number | Yes | -- | Chain ID to filter chain-specific pairs |
selectedPair | string | No | -- | Currently selected pair symbol |
onSelect | (pair: TradingPair) => void | Yes | -- | Selection callback |
showIcons | boolean | No | true | Show icons from PAIR_ICONS |
showInactive | boolean | No | false | Show inactive (greyed) pairs |
style | ViewStyle | No | -- | Container style |
itemStyle | ViewStyle | No | -- | Individual item style |
testID | string | No | -- | Test ID |
PAIR_ICONS Constant
The PAIR_ICONS constant maps asset symbols to their icon URIs.
import { PAIR_ICONS } from '@one_deploy/sdk';
// PAIR_ICONS: Record<string, string>
console.log(PAIR_ICONS['BTC']);
// 'https://assets.one23.io/icons/btc.png'
console.log(PAIR_ICONS['ETH']);
// 'https://assets.one23.io/icons/eth.png'
console.log(PAIR_ICONS['USDT']);
// 'https://assets.one23.io/icons/usdt.png'
console.log(PAIR_ICONS['SOL']);
// 'https://assets.one23.io/icons/sol.png'
Available icons:
| Asset | Key | Description |
|---|---|---|
| Bitcoin | BTC | Bitcoin icon |
| Ethereum | ETH | Ethereum icon |
| Tether | USDT | Tether USD icon |
| USD Coin | USDC | USDC icon |
| Solana | SOL | Solana icon |
| BNB | BNB | BNB icon |
| Avalanche | AVAX | Avalanche icon |
| Polygon | MATIC | Polygon icon |
| Chainlink | LINK | Chainlink icon |
| Uniswap | UNI | Uniswap icon |
TradingPair Type
interface TradingPair {
/** Unique pair identifier, e.g. "BTC_USDT". */
symbol: string;
/** Base asset symbol, e.g. "BTC". */
baseAsset: string;
/** Quote asset symbol, e.g. "USDT". */
quoteAsset: string;
/** Chain ID where this pair is traded. */
chainId: number;
/** Whether the pair is currently available for new orders. */
isActive: boolean;
/** Minimum order size in quote currency. */
minOrderSize: number;
/** Maximum order size in quote currency, or null for unlimited. */
maxOrderSize: number | null;
/** Price precision (decimal places). */
pricePrecision: number;
/** Quantity precision (decimal places). */
quantityPrecision: number;
}
Usage Examples
With Strategy and Chain Filtering
import { useState } from 'react';
import { View, Text } from 'react-native';
import { OnePairSelector } from '@one_deploy/sdk';
import type { TradingPair } from '@one_deploy/sdk';
function PairSelection({
strategyId,
chainId,
}: {
strategyId: string;
chainId: number;
}) {
const [selectedPair, setSelectedPair] = useState<TradingPair | null>(null);
return (
<View>
<Text style={styles.heading}>Select Trading Pair</Text>
<OnePairSelector
strategyId={strategyId}
chainId={chainId}
selectedPair={selectedPair?.symbol}
showIcons={true}
onSelect={(pair) => setSelectedPair(pair)}
/>
{selectedPair && (
<View style={styles.info}>
<Text>Pair: {selectedPair.baseAsset}/{selectedPair.quoteAsset}</Text>
<Text>
Order range: {selectedPair.minOrderSize}
{selectedPair.maxOrderSize ? ` - ${selectedPair.maxOrderSize}` : '+'}
{' '}{selectedPair.quoteAsset}
</Text>
</View>
)}
</View>
);
}
Custom Styling
import { OnePairSelector } from '@one_deploy/sdk';
function StyledPairSelector() {
return (
<OnePairSelector
strategyId="strat_abc123"
chainId={8453}
showIcons={true}
showInactive={false}
style={{
backgroundColor: '#0f0f1a',
borderRadius: 16,
padding: 12,
}}
itemStyle={{
flexDirection: 'row',
alignItems: 'center',
paddingVertical: 14,
paddingHorizontal: 16,
borderRadius: 10,
marginBottom: 6,
backgroundColor: '#1a1a2e',
}}
onSelect={(pair) => console.log('Selected:', pair.symbol)}
/>
);
}
Including Inactive Pairs
import { OnePairSelector } from '@one_deploy/sdk';
function PairSelectorWithInactive() {
return (
<OnePairSelector
strategyId="strat_abc123"
chainId={8453}
showInactive={true}
onSelect={(pair) => {
// Only active pairs fire onSelect
console.log('Selected active pair:', pair.symbol);
}}
/>
);
}
Building a Custom Pair Selector with PAIR_ICONS
If you need complete control over the pair list rendering, use the API directly with PAIR_ICONS.
import { useState, useEffect } from 'react';
import { View, Text, Image, Pressable, FlatList } from 'react-native';
import { OneEngineClient, PAIR_ICONS } from '@one_deploy/sdk';
import type { TradingPair } from '@one_deploy/sdk';
function CustomPairSelector({
engine,
onSelect,
}: {
engine: OneEngineClient;
onSelect: (pair: TradingPair) => void;
}) {
const [pairs, setPairs] = useState<TradingPair[]>([]);
const [selected, setSelected] = useState<string | null>(null);
useEffect(() => {
engine.getTradingPairs().then((allPairs) => {
setPairs(allPairs.filter((p) => p.isActive));
});
}, []);
return (
<FlatList
data={pairs}
keyExtractor={(item) => item.symbol}
renderItem={({ item }) => (
<Pressable
onPress={() => {
setSelected(item.symbol);
onSelect(item);
}}
style={[
styles.pairRow,
selected === item.symbol && styles.selectedRow,
]}
>
<View style={styles.iconContainer}>
<Image
source={{ uri: PAIR_ICONS[item.baseAsset] }}
style={styles.icon}
/>
<Image
source={{ uri: PAIR_ICONS[item.quoteAsset] }}
style={[styles.icon, styles.quoteIcon]}
/>
</View>
<View style={styles.pairInfo}>
<Text style={styles.pairSymbol}>
{item.baseAsset}/{item.quoteAsset}
</Text>
<Text style={styles.pairDetail}>
Min: {item.minOrderSize} {item.quoteAsset}
</Text>
</View>
</Pressable>
)}
/>
);
}
const styles = {
pairRow: {
flexDirection: 'row' as const,
alignItems: 'center' as const,
padding: 12,
borderBottomWidth: 1,
borderBottomColor: '#222',
},
selectedRow: {
backgroundColor: '#1a1a3e',
},
iconContainer: {
flexDirection: 'row' as const,
width: 48,
},
icon: {
width: 28,
height: 28,
borderRadius: 14,
},
quoteIcon: {
marginLeft: -10,
},
pairInfo: {
marginLeft: 12,
},
pairSymbol: {
color: '#fff',
fontWeight: '600' as const,
fontSize: 15,
},
pairDetail: {
color: '#888',
fontSize: 12,
marginTop: 2,
},
};
Controlled State with Navigation
import { useState } from 'react';
import { View, Text, Pressable } from 'react-native';
import { OnePairSelector } from '@one_deploy/sdk';
import type { TradingPair } from '@one_deploy/sdk';
function PairStepWithNav({
strategyId,
chainId,
onBack,
onNext,
}: {
strategyId: string;
chainId: number;
onBack: () => void;
onNext: (pair: TradingPair) => void;
}) {
const [selectedPair, setSelectedPair] = useState<TradingPair | null>(null);
return (
<View style={styles.container}>
<Text style={styles.heading}>Select Trading Pair</Text>
<Text style={styles.subtext}>
Choose the asset pair the AI agent will trade.
</Text>
<OnePairSelector
strategyId={strategyId}
chainId={chainId}
selectedPair={selectedPair?.symbol}
showIcons={true}
onSelect={setSelectedPair}
/>
<View style={styles.navRow}>
<Pressable onPress={onBack}>
<Text>Back</Text>
</Pressable>
<Pressable
onPress={() => selectedPair && onNext(selectedPair)}
disabled={!selectedPair}
>
<Text style={selectedPair ? styles.nextActive : styles.nextDisabled}>
Next
</Text>
</Pressable>
</View>
</View>
);
}
Next Steps
- Creating Orders -- combine the pair selector with the full builder flow.
- Trading Pairs -- full guide on trading pairs and the getTradingPairs API.
- OneChainSelector -- the chain selector that precedes pair selection.