Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ IDEWorkspaceChecks.plist
android-release.bundle.map
ios-release.bundle.map
keystores/
.run.env

# Debugging
overrideTheme.json
Expand Down
59 changes: 58 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
# Edge React GUI - Agent Guidelines

## Initialization

**Before starting any task, ensure `docs/` is in context:**

1. **Use `find docs/ -name "*.md" -type f`** to recursively list all `.md` files in `docs/` folder to get an index of available documentation
2. **Read relevant docs** to understand existing conventions, patterns, and business logic before implementing features

## Workflow

### Documentation Management

- **Document lessons learned** when prompts contain "always", "remember", "never" or similar memory keywords
- **Create markdown files** in `docs/` folder for conventions, business logic, and codebase patterns discovered
- **Amend existing docs** rather than creating duplicates to keep knowledge base organized and succinct
- **Prioritize documenting** coding conventions, architectural patterns, and business rules
- **All `.md` files in `docs/` must be indexed** in the Documentation section below with "When to read" and "Summary" descriptions

## Package Manager

- **Use Yarn v1** instead of npm for all package management and script execution
Expand All @@ -9,7 +26,8 @@

## Build/Test/Lint Commands

- `yarn lint` - Run ESLint on entire codebase
- `yarn lint` - Run ESLint on entire codebase (only use when working on warning cleanup)
- `yarn lint --quiet` - Run ESLint on entire codebase and only get error (Prefer this usage always)
- `yarn fix` - Auto-fix linting issues and deduplicate yarn
- `yarn test` - Run Jest tests (single run)
- `yarn watch` - Run Jest tests in watch mode
Expand Down Expand Up @@ -51,3 +69,42 @@
- Create pseudo-merge commits with "future! branch-name" for dependent features
- Use `git rebase --onto` to update dependent branches when base changes
- Remove future commits by rebasing onto master once dependencies are merged

## Documentation

The following documentation files provide detailed guidance for specific areas of development. **Read the relevant documentation before starting work** in these areas:

### `docs/component-styling-guidelines.md`

**When to read**: Before styling components or converting inline styles to styled components
**Summary**: Guidelines for using the `styled` HOC, file structure patterns, and avoiding inline styles. Essential for maintaining consistent component styling across the codebase.

### `docs/localization-guidelines.md`

**When to read**: Before adding any UI text or working with user-facing strings
**Summary**: Mandatory guidelines for localizing all UI strings using `lstrings` from `en_US.ts`. Covers naming conventions, parameter handling, and implementation steps for internationalization.

### `docs/MAESTRO.md`

**When to read**: When setting up or running end-to-end tests, or when working on test automation
**Summary**: Complete setup guide for Maestro mobile testing framework. Includes installation instructions, running tests, and creating new tests with Maestro Studio.

### `docs/GUI_PLUGINS_ARCHITECTURE.md`

**When to read**: When working on fiat on/off ramp features, payment integrations, or plugin system
**Summary**: Comprehensive architecture guide for the fiat plugin system. Covers provider implementations, payment method configurations, regional restrictions, and integration patterns for buy/sell cryptocurrency features.

### `docs/scene-architecture-patterns.md`

**When to read**: Before creating new scenes or modifying existing scene components
**Summary**: Critical architectural patterns for Edge scenes. Covers the fundamental rule that scenes must never implement custom headers (managed by react-navigation), proper SceneWrapper usage, and navigation configuration patterns. Includes TradeCreateScene case study showing common architectural violations to avoid.

### `docs/payment-type-icons.md`

**When to read**: When working with payment type icons in fiat plugins or payment method displays
**Summary**: Explains the payment type icon mapping system for displaying appropriate icons for different payment methods. Covers usage with `getPaymentTypeIcon` utility, integration with PaymentOptionCard, direct and fallback mappings, and how to add new payment types.

### `docs/ramp-plugin-migration-guide.md`

**When to read**: Before migrating ramp plugins from legacy provider architecture to new ramp plugin architecture or when creating new ramp plugins
**Summary**: Comprehensive migration guide for removing FiatPluginUi abstraction and using direct API imports. Covers migration of toasts, modals, navigation, permissions (with important boolean logic inversion note), wallet operations, and environment configuration requirements. Includes detailed steps for creating init options cleaners, validating plugin initialization, and registering plugins in envConfig. Also explains how to migrate getSupportedAssets initialization logic to an internal fetchProviderConfig function with 2-minute TTL caching. Essential for converting legacy fiat providers to new ramp plugins and ensuring proper type safety.
Binary file added design.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
54 changes: 54 additions & 0 deletions docs/component-styling-guidelines.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Component Styling Guidelines

## File Structure

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per long discussion: remove all .md files from the PR, add to .gitignore

- **Types first**: Type definitions at the top serve as documentation
- **Exports second**: Component exports immediately after types for visibility
- **Styled components third**: All styled components after the main export (more relevant to component structure)
- **Utility functions fourth**: Helper functions and components scoped to the file come after styled components
- **Styles last**: cacheStyles objects at the bottom of the file

## Styling Patterns
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When you move these docs to your own personal shared dev docs location (location TBD), add some TODOs to craft new rules/scripts for:

  • Naming conventions for component and prop names
  • Auto /** documentation **/ expanding on meaning and implementation details
  • Thresholds for inlines vs abstracted implementations


- **Always use `styled` HOC** from `@src/components/hoc/styled.tsx` instead of inline styles
- **Run `yarn eslint --fix`** on all files to format and fix lint errors automatically
- **EdgeText with styled**: EdgeText can be used with styled HOC since it accepts a `style` prop
- **Raw text fallback**: If styled EdgeText causes raw text ESLint errors, use regular EdgeText with cacheStyles
- **Avoid inline styles**: Use styled HOC or cacheStyles, never inline style objects

## Example File Structure

```tsx
// Types first
interface Props {
// ...
}

// Exports second
export const MyComponent = (props: Props) => {
return (
<Container>
<StyledText>{formatText('Hello')}</StyledText>
</Container>
)
}

// Styled components third (more relevant to component structure)
const Container = styled(View)({
// styles
})

const StyledText = styled(EdgeText)({
// styles
})

// Utility functions fourth (scoped to this file)
const formatText = (text: string): string => {
return text.toUpperCase()
}

// Styles last (if needed for complex cases)
const styles = cacheStyles({
// fallback styles
})
```
82 changes: 82 additions & 0 deletions docs/localization-guidelines.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Localization Guidelines

## Core Principle

**ALWAYS put strings displayed in the UI in the `@src/locales/en_US.ts` file for localization.** Use `lstrings.string_name` to access the string.

## String Naming Convention

### Basic Strings

- Use descriptive, hierarchical naming: `component_context_description`
- Example: `trade_region_select_buy_crypto`, `settings_account_title`

### Parameterized Strings

If a string uses sprintf and `%s` or replacements, suffix the string with parameter indicators:

- **Single parameter**: `_s` suffix
- Example: `buy_1s: 'Buy %1$s'`
- **Two parameters**: `_2s` suffix
- Example: `error_balance_below_minimum_to_stake_2s: 'Your balance of %1$s does not meet the minimum %2$s required to stake.'`
- **Multiple parameters**: `_ns` suffix (where n is the number)
- Example: `_3s`, `_4s`, `_5s` etc.

## Implementation Steps

1. **Identify hardcoded strings** in UI components
2. **Add strings to `en_US.ts`** with appropriate naming and parameter suffixes
3. **Replace hardcoded strings** with `lstrings.string_name` references
4. **Import lstrings** from `'../../locales/strings'` (adjust path as needed)

## Examples

### Before (Hardcoded)

```tsx
<EdgeText>Buy Crypto</EdgeText>
<EdgeText>Start in 4 Easy Steps</EdgeText>
<EdgeText>{`Step 1: Select Your Region`}</EdgeText>
```

### After (Localized)

```tsx
// In en_US.ts
export const strings = {
trade_region_select_buy_crypto: 'Buy Crypto',
trade_region_select_start_steps: 'Start in 4 Easy Steps',
trade_region_select_step_1: ' Select Your Region for personalized options',
// ...
}

// In component
import { lstrings } from '../../locales/strings'

<EdgeText>{lstrings.trade_region_select_buy_crypto}</EdgeText>
<EdgeText>{lstrings.trade_region_select_start_steps}</EdgeText>
<EdgeText>{lstrings.trade_region_select_step_1}</EdgeText>
```

### Parameterized Example

```tsx
// In en_US.ts
buy_1s: 'Buy %1$s',
error_balance_below_minimum_2s: 'Balance %1$s below minimum %2$s',

// In component
<EdgeText>{sprintf(lstrings.buy_1s, currencyCode)}</EdgeText>
<EdgeText>{sprintf(lstrings.error_balance_below_minimum_2s, balance, minimum)}</EdgeText>
```

## Benefits

- **Internationalization ready**: All strings can be translated to other languages
- **Consistency**: Centralized string management prevents duplicates
- **Maintainability**: Easy to update strings across the entire app
- **Type safety**: TypeScript ensures string keys exist

## Remember

This is a **mandatory** practice for all UI strings. No exceptions should be made for hardcoded strings in user-facing components.
122 changes: 122 additions & 0 deletions docs/payment-type-icons.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# Payment Type Icons

This document explains how to use the payment type icon mapping system for displaying appropriate icons for different payment methods in the fiat plugin system.

## Overview

The payment type icon system provides a consistent way to map `FiatPaymentType` values to their corresponding theme icon keys. This ensures that payment methods are displayed with the correct visual representation across the application.

## Usage

### Basic Usage

```typescript
import { getPaymentTypeIcon } from '../util/paymentTypeIcons'
import { useTheme } from '../services/ThemeContext'

const MyComponent = () => {
const theme = useTheme()
const paymentType = 'applepay' // FiatPaymentType

const icon = getPaymentTypeIcon(paymentType, theme)
// Returns: { uri: 'path/to/apple-pay-icon.png' }
}
```

### Integration with PaymentOptionCard

When rendering payment options from quotes, use the first payment type to determine the icon:

```typescript
const QuoteResult = ({ quote }) => {
const theme = useTheme()

// Get icon for the first payment type, fallback to partner icon
const paymentTypeIcon = quote.paymentTypes[0]
? getPaymentTypeIcon(quote.paymentTypes[0], theme)
: undefined
const icon = paymentTypeIcon ?? { uri: quote.partnerIcon }

return (
<PaymentOptionCard
title={quote.paymentTypes.join(', ')}
icon={icon}
// ... other props
/>
)
}
```

## Payment Type Mappings

### Direct Mappings

These payment types have dedicated icons in the theme:

- `applepay` → `paymentTypeLogoApplePay`
- `credit` → `paymentTypeLogoCreditCard`
- `fasterpayments` → `paymentTypeLogoFasterPayments`
- `googlepay` → `paymentTypeLogoGooglePay`
- `ideal` → `paymentTypeLogoIdeal`
- `interac` → `paymentTypeLogoInterac`
- `payid` → `paymentTypeLogoPayid`
- `paypal` → `paymentTypeLogoPaypal`
- `pix` → `paymentTypeLogoPix`
- `revolut` → `paymentTypeLogoRevolut`
- `venmo` → `paymentTypeLogoVenmo`

### Fallback Mappings

These payment types use the generic bank transfer icon as a fallback:

- `ach` → `paymentTypeLogoBankTransfer`
- `colombiabank` → `paymentTypeLogoBankTransfer`
- `directtobank` → `paymentTypeLogoBankTransfer`
- `iach` → `paymentTypeLogoBankTransfer`
- `iobank` → `paymentTypeLogoBankTransfer`
- `mexicobank` → `paymentTypeLogoBankTransfer`
- `pse` → `paymentTypeLogoBankTransfer`
- `sepa` → `paymentTypeLogoBankTransfer`
- `spei` → `paymentTypeLogoBankTransfer`
- `turkishbank` → `paymentTypeLogoBankTransfer`
- `wire` → `paymentTypeLogoBankTransfer`

## API Reference

### `getPaymentTypeIcon(paymentType: FiatPaymentType, theme: Theme): ImageProp | undefined`

Returns the theme icon for a given payment type.

**Parameters:**
- `paymentType`: The payment type to get the icon for
- `theme`: The theme object containing the icon images

**Returns:**
- `ImageProp`: The icon image object (`{ uri: string } | number`)
- `undefined`: If the payment type doesn't have a corresponding icon

### `getPaymentTypeThemeKey(paymentType: FiatPaymentType): keyof Theme | null`

Returns just the theme key for a payment type without requiring the theme object.

**Parameters:**
- `paymentType`: The payment type to get the theme key for

**Returns:**
- `keyof Theme`: The theme key string
- `null`: If the payment type doesn't have a corresponding theme key

## Adding New Payment Types

To add support for a new payment type:

1. Add the payment type to the `FiatPaymentType` union in `fiatPluginTypes.ts`
2. Add the corresponding icon to the theme in `types/Theme.ts`
3. Update the `paymentTypeToThemeKey` mapping in `util/paymentTypeIcons.ts`
4. Add the icon assets to all theme variations (edgeLight, edgeDark, etc.)

## Notes

- Payment types that are primarily bank-based use the generic bank transfer icon as a reasonable fallback
- The system is designed to be extensible - new payment types can be added without breaking existing functionality
- Always provide a fallback (like the partner icon) when using payment type icons in case the mapping returns undefined
Loading
Loading