Skip to content

Commit 366f117

Browse files
authored
Merge pull request #5740 from EdgeApp/sam/ramp-plugin-full
Full New Ramp Plugin Rearchitecture
2 parents b59e66b + 43b0e1f commit 366f117

File tree

81 files changed

+13065
-250
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

81 files changed

+13065
-250
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ IDEWorkspaceChecks.plist
1717
android-release.bundle.map
1818
ios-release.bundle.map
1919
keystores/
20+
.run.env
2021

2122
# Debugging
2223
overrideTheme.json

AGENTS.md

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,22 @@
11
# Edge React GUI - Agent Guidelines
22

3+
## Initialization
4+
5+
**Before starting any task, ensure `docs/` is in context:**
6+
7+
1. **Use `find docs/ -name "*.md" -type f`** to recursively list all `.md` files in `docs/` folder to get an index of available documentation
8+
2. **Read relevant docs** to understand existing conventions, patterns, and business logic before implementing features
9+
10+
## Workflow
11+
12+
### Documentation Management
13+
14+
- **Document lessons learned** when prompts contain "always", "remember", "never" or similar memory keywords
15+
- **Create markdown files** in `docs/` folder for conventions, business logic, and codebase patterns discovered
16+
- **Amend existing docs** rather than creating duplicates to keep knowledge base organized and succinct
17+
- **Prioritize documenting** coding conventions, architectural patterns, and business rules
18+
- **All `.md` files in `docs/` must be indexed** in the Documentation section below with "When to read" and "Summary" descriptions
19+
320
## Package Manager
421

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

1027
## Build/Test/Lint Commands
1128

12-
- `yarn lint` - Run ESLint on entire codebase
29+
- `yarn lint` - Run ESLint on entire codebase (only use when working on warning cleanup)
30+
- `yarn lint --quiet` - Run ESLint on entire codebase and only get error (Prefer this usage always)
1331
- `yarn fix` - Auto-fix linting issues and deduplicate yarn
1432
- `yarn test` - Run Jest tests (single run)
1533
- `yarn watch` - Run Jest tests in watch mode
@@ -51,3 +69,42 @@
5169
- Create pseudo-merge commits with "future! branch-name" for dependent features
5270
- Use `git rebase --onto` to update dependent branches when base changes
5371
- Remove future commits by rebasing onto master once dependencies are merged
72+
73+
## Documentation
74+
75+
The following documentation files provide detailed guidance for specific areas of development. **Read the relevant documentation before starting work** in these areas:
76+
77+
### `docs/component-styling-guidelines.md`
78+
79+
**When to read**: Before styling components or converting inline styles to styled components
80+
**Summary**: Guidelines for using the `styled` HOC, file structure patterns, and avoiding inline styles. Essential for maintaining consistent component styling across the codebase.
81+
82+
### `docs/localization-guidelines.md`
83+
84+
**When to read**: Before adding any UI text or working with user-facing strings
85+
**Summary**: Mandatory guidelines for localizing all UI strings using `lstrings` from `en_US.ts`. Covers naming conventions, parameter handling, and implementation steps for internationalization.
86+
87+
### `docs/MAESTRO.md`
88+
89+
**When to read**: When setting up or running end-to-end tests, or when working on test automation
90+
**Summary**: Complete setup guide for Maestro mobile testing framework. Includes installation instructions, running tests, and creating new tests with Maestro Studio.
91+
92+
### `docs/GUI_PLUGINS_ARCHITECTURE.md`
93+
94+
**When to read**: When working on fiat on/off ramp features, payment integrations, or plugin system
95+
**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.
96+
97+
### `docs/scene-architecture-patterns.md`
98+
99+
**When to read**: Before creating new scenes or modifying existing scene components
100+
**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.
101+
102+
### `docs/payment-type-icons.md`
103+
104+
**When to read**: When working with payment type icons in fiat plugins or payment method displays
105+
**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.
106+
107+
### `docs/ramp-plugin-migration-guide.md`
108+
109+
**When to read**: Before migrating ramp plugins from legacy provider architecture to new ramp plugin architecture or when creating new ramp plugins
110+
**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.

bity-ramp-plugin-verification.md

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# Bity Ramp Plugin Verification Report
2+
3+
## Overview
4+
The Bity ramp plugin implementation has been verified to correctly support the new `checkSupport` API as described in the ramp plugin architecture documentation.
5+
6+
## Verification Results
7+
8+
### 1. Plugin Interface ✅
9+
The plugin correctly implements both required methods:
10+
- `checkSupport: (request: RampCheckSupportRequest) => Promise<RampSupportResult>`
11+
- `fetchQuote: (request: RampQuoteRequest) => Promise<RampQuoteResult[]>`
12+
13+
### 2. Shared Validation Logic ✅
14+
Both methods share the same validation logic through helper functions:
15+
- `isRegionSupported()` - Used by both checkSupport (line 607) and fetchQuote (line 671)
16+
- `isCryptoSupported()` - Used by both checkSupport (lines 612-618) and fetchQuote (line 676)
17+
- `findCryptoCurrency()` - Used for finding crypto in provider's currency list
18+
- `findFiatCurrency()` - Used for finding fiat in provider's currency list
19+
20+
### 3. Return Types ✅
21+
- `checkSupport` correctly returns `{ supported: boolean }` (RampSupportResult type)
22+
- `fetchQuote` correctly returns `RampQuoteResult[]` array
23+
24+
### 4. Error Handling ✅
25+
- **checkSupport**: Catches all errors and returns `{ supported: false }` instead of throwing (lines 648-652)
26+
- **fetchQuote**: Returns empty array `[]` for all error conditions (lines 673, 677, 686, 699, 711, 743, 751, 759, 781, 791, 810)
27+
28+
### 5. Architecture Compliance ✅
29+
The implementation follows all patterns from the documentation:
30+
- Fast local checks in `checkSupport` before API calls
31+
- Shared provider config fetching with 2-minute TTL cache
32+
- No unnecessary API calls for unsupported pairs
33+
- Clear separation of concerns between support checking and quote fetching
34+
35+
## Key Implementation Details
36+
37+
### Helper Functions
38+
```typescript
39+
// Region validation (line 520)
40+
function isRegionSupported(regionCode: FiatPluginRegionCode): boolean
41+
42+
// Crypto validation (line 527)
43+
function isCryptoSupported(
44+
pluginId: string,
45+
tokenId: EdgeTokenId,
46+
direction: 'buy' | 'sell'
47+
): boolean
48+
49+
// Currency finders (lines 539 & 575)
50+
function findCryptoCurrency(...)
51+
function findFiatCurrency(...)
52+
```
53+
54+
### Caching Strategy
55+
- Provider config cached for 2 minutes (line 277: `CACHE_TTL_MS = 2 * 60 * 1000`)
56+
- Cache checked before API calls (line 409)
57+
- Graceful fallback to cached data on API failures
58+
59+
### Support Checking Flow
60+
1. Quick local region check
61+
2. Quick local crypto check against no-KYC list
62+
3. Fetch provider config (cached)
63+
4. Check fiat currency support
64+
5. Return boolean result
65+
66+
### Quote Fetching Flow
67+
1. Reuse same validation helpers as checkSupport
68+
2. Skip API calls if validation fails
69+
3. Return empty array for any failures
70+
4. Only throw for actual critical errors
71+
72+
## Example Usage
73+
74+
```typescript
75+
// Check support across multiple plugins
76+
const supportResults = await Promise.all(
77+
plugins.map(plugin => plugin.checkSupport(request))
78+
)
79+
80+
// Filter to supported plugins
81+
const supportedPlugins = plugins.filter(
82+
(plugin, index) => supportResults[index].supported
83+
)
84+
85+
// Only fetch quotes from supported plugins
86+
const quotes = await Promise.all(
87+
supportedPlugins.map(plugin => plugin.fetchQuote(quoteRequest))
88+
)
89+
```
90+
91+
## Conclusion
92+
93+
The Bity ramp plugin implementation fully complies with the new `checkSupport` API architecture. It demonstrates:
94+
- Proper type safety with TypeScript
95+
- Efficient caching to minimize API calls
96+
- Shared validation logic between methods
97+
- Correct error handling patterns
98+
- Clean separation of concerns
99+
100+
The implementation serves as a good example for migrating other ramp plugins to the new architecture.

design.png

541 KB
Loading
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Component Styling Guidelines
2+
3+
## File Structure
4+
5+
- **Types first**: Type definitions at the top serve as documentation
6+
- **Exports second**: Component exports immediately after types for visibility
7+
- **Styled components third**: All styled components after the main export (more relevant to component structure)
8+
- **Utility functions fourth**: Helper functions and components scoped to the file come after styled components
9+
- **Styles last**: cacheStyles objects at the bottom of the file
10+
11+
## Styling Patterns
12+
13+
- **Always use `styled` HOC** from `@src/components/hoc/styled.tsx` instead of inline styles
14+
- **Run `yarn eslint --fix`** on all files to format and fix lint errors automatically
15+
- **EdgeText with styled**: EdgeText can be used with styled HOC since it accepts a `style` prop
16+
- **Raw text fallback**: If styled EdgeText causes raw text ESLint errors, use regular EdgeText with cacheStyles
17+
- **Avoid inline styles**: Use styled HOC or cacheStyles, never inline style objects
18+
19+
## Example File Structure
20+
21+
```tsx
22+
// Types first
23+
interface Props {
24+
// ...
25+
}
26+
27+
// Exports second
28+
export const MyComponent = (props: Props) => {
29+
return (
30+
<Container>
31+
<StyledText>{formatText('Hello')}</StyledText>
32+
</Container>
33+
)
34+
}
35+
36+
// Styled components third (more relevant to component structure)
37+
const Container = styled(View)({
38+
// styles
39+
})
40+
41+
const StyledText = styled(EdgeText)({
42+
// styles
43+
})
44+
45+
// Utility functions fourth (scoped to this file)
46+
const formatText = (text: string): string => {
47+
return text.toUpperCase()
48+
}
49+
50+
// Styles last (if needed for complex cases)
51+
const styles = cacheStyles({
52+
// fallback styles
53+
})
54+
```

docs/localization-guidelines.md

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# Localization Guidelines
2+
3+
## Core Principle
4+
5+
**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.
6+
7+
## String Naming Convention
8+
9+
### Basic Strings
10+
11+
- Use descriptive, hierarchical naming: `component_context_description`
12+
- Example: `trade_region_select_buy_crypto`, `settings_account_title`
13+
14+
### Parameterized Strings
15+
16+
If a string uses sprintf and `%s` or replacements, suffix the string with parameter indicators:
17+
18+
- **Single parameter**: `_s` suffix
19+
- Example: `buy_1s: 'Buy %1$s'`
20+
- **Two parameters**: `_2s` suffix
21+
- Example: `error_balance_below_minimum_to_stake_2s: 'Your balance of %1$s does not meet the minimum %2$s required to stake.'`
22+
- **Multiple parameters**: `_ns` suffix (where n is the number)
23+
- Example: `_3s`, `_4s`, `_5s` etc.
24+
25+
## Implementation Steps
26+
27+
1. **Identify hardcoded strings** in UI components
28+
2. **Add strings to `en_US.ts`** with appropriate naming and parameter suffixes
29+
3. **Replace hardcoded strings** with `lstrings.string_name` references
30+
4. **Import lstrings** from `'../../locales/strings'` (adjust path as needed)
31+
32+
## Examples
33+
34+
### Before (Hardcoded)
35+
36+
```tsx
37+
<EdgeText>Buy Crypto</EdgeText>
38+
<EdgeText>Start in 4 Easy Steps</EdgeText>
39+
<EdgeText>{`Step 1: Select Your Region`}</EdgeText>
40+
```
41+
42+
### After (Localized)
43+
44+
```tsx
45+
// In en_US.ts
46+
export const strings = {
47+
trade_region_select_buy_crypto: 'Buy Crypto',
48+
trade_region_select_start_steps: 'Start in 4 Easy Steps',
49+
trade_region_select_step_1: ' Select Your Region for personalized options',
50+
// ...
51+
}
52+
53+
// In component
54+
import { lstrings } from '../../locales/strings'
55+
56+
<EdgeText>{lstrings.trade_region_select_buy_crypto}</EdgeText>
57+
<EdgeText>{lstrings.trade_region_select_start_steps}</EdgeText>
58+
<EdgeText>{lstrings.trade_region_select_step_1}</EdgeText>
59+
```
60+
61+
### Parameterized Example
62+
63+
```tsx
64+
// In en_US.ts
65+
buy_1s: 'Buy %1$s',
66+
error_balance_below_minimum_2s: 'Balance %1$s below minimum %2$s',
67+
68+
// In component
69+
<EdgeText>{sprintf(lstrings.buy_1s, currencyCode)}</EdgeText>
70+
<EdgeText>{sprintf(lstrings.error_balance_below_minimum_2s, balance, minimum)}</EdgeText>
71+
```
72+
73+
## Benefits
74+
75+
- **Internationalization ready**: All strings can be translated to other languages
76+
- **Consistency**: Centralized string management prevents duplicates
77+
- **Maintainability**: Easy to update strings across the entire app
78+
- **Type safety**: TypeScript ensures string keys exist
79+
80+
## Remember
81+
82+
This is a **mandatory** practice for all UI strings. No exceptions should be made for hardcoded strings in user-facing components.

0 commit comments

Comments
 (0)