Skip to content
Merged
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
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ New endpoint = handler in `handlers.rs` + route in `app.rs` + method on `Explore
- `config/{env}.toml` selected by `--env` (both binaries take it; default `default` → `config/default.toml`). Env vars with `APP_` prefix override (e.g. `APP_DATABASE_URL`); `.env` is loaded via dotenv.
- `data_source`: `"postgres"` (normal) or `"node"` (DB-less passthrough).
- `developer_mode` / `cleanup_on_start`: truncate all tables on shutdown / startup.
- `ride_*_referrer_fee_percent` must match clutch-node config or RidePay fee display drifts.
- `ride_*_referrer_fee_bps` must match clutch-node config or RidePay fee display drifts.

### DB schema / migrations

Expand Down
4 changes: 2 additions & 2 deletions backend/config/default.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ seq_api_key = ""
allowed_origins = "*"

# Must match clutch-node config for accurate RidePay referrer fee display.
ride_request_referrer_fee_percent = 2
ride_offer_referrer_fee_percent = 2
ride_request_referrer_fee_bps = 200
ride_offer_referrer_fee_bps = 200
16 changes: 8 additions & 8 deletions backend/src/explorer/configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ fn default_developer_mode() -> bool {
false
}

fn default_referrer_fee_percent() -> u8 {
2
fn default_referrer_fee_bps() -> u16 {
200
}

#[derive(Debug, Deserialize, Clone)]
Expand Down Expand Up @@ -65,12 +65,12 @@ pub struct AppConfig {
pub indexer_poll_interval_ms: u64,
#[serde(default = "default_indexer_start_height")]
pub indexer_start_height: u64,
/// Match clutch-node `ride_request_referrer_fee_percent` for RidePay display.
#[serde(default = "default_referrer_fee_percent")]
pub ride_request_referrer_fee_percent: u8,
/// Match clutch-node `ride_offer_referrer_fee_percent` for RidePay display.
#[serde(default = "default_referrer_fee_percent")]
pub ride_offer_referrer_fee_percent: u8,
/// Match clutch-node `ride_request_referrer_fee_bps` for RidePay display.
#[serde(default = "default_referrer_fee_bps")]
pub ride_request_referrer_fee_bps: u16,
/// Match clutch-node `ride_offer_referrer_fee_bps` for RidePay display.
#[serde(default = "default_referrer_fee_bps")]
pub ride_offer_referrer_fee_bps: u16,
}

impl AppConfig {
Expand Down
16 changes: 8 additions & 8 deletions backend/src/explorer/indexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ pub struct IndexerService {
pool: PgPool,
poll_interval_ms: u64,
start_height: u64,
ride_request_referrer_fee_percent: u8,
ride_offer_referrer_fee_percent: u8,
ride_request_referrer_fee_bps: u16,
ride_offer_referrer_fee_bps: u16,
}

/// Pure decision: has the chain diverged from what's already indexed, given the node's
Expand All @@ -47,16 +47,16 @@ impl IndexerService {
pool: PgPool,
poll_interval_ms: u64,
start_height: u64,
ride_request_referrer_fee_percent: u8,
ride_offer_referrer_fee_percent: u8,
ride_request_referrer_fee_bps: u16,
ride_offer_referrer_fee_bps: u16,
) -> Self {
Self {
source,
pool,
poll_interval_ms,
start_height,
ride_request_referrer_fee_percent,
ride_offer_referrer_fee_percent,
ride_request_referrer_fee_bps,
ride_offer_referrer_fee_bps,
}
}

Expand Down Expand Up @@ -372,8 +372,8 @@ impl IndexerService {
enrich_transactions(
&self.pool,
&mut txs,
self.ride_request_referrer_fee_percent,
self.ride_offer_referrer_fee_percent,
self.ride_request_referrer_fee_bps,
self.ride_offer_referrer_fee_bps,
)
.await;

Expand Down
29 changes: 15 additions & 14 deletions backend/src/explorer/referrer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ pub fn normalize_hex_address(value: &str) -> Option<String> {
Some(format!("0x{}", body.to_ascii_lowercase()))
}

/// Match clutch-node RidePay referrer fee rounding (ceiling division).
pub fn referrer_fee_ceiling(percent: u8, fare: u64) -> u64 {
if percent == 0 || fare == 0 {
/// Match clutch-node RidePay referrer fee rounding (basis points, floor division).
pub fn referrer_fee_bps(bps: u16, fare: u64) -> u64 {
if bps == 0 || fare == 0 {
return 0;
}
(percent as u64 * fare + 99) / 100
(fare as u128 * bps as u128 / 10_000) as u64
}

pub fn parse_referrer(arguments: &Value) -> Option<String> {
Expand Down Expand Up @@ -70,8 +70,8 @@ async fn load_payload(
pub async fn enrich_transactions(
pool: &PgPool,
txs: &mut [RawTransaction],
request_fee_percent: u8,
offer_fee_percent: u8,
request_fee_bps: u16,
offer_fee_bps: u16,
) {
let mut block_cache: HashMap<String, Value> = HashMap::new();
for tx in txs.iter() {
Expand Down Expand Up @@ -131,11 +131,11 @@ pub async fn enrich_transactions(

let mut request_fee = 0u64;
let mut offer_fee = 0u64;
if request_referrer.is_some() && request_fee_percent > 0 {
request_fee = referrer_fee_ceiling(request_fee_percent, fare);
if request_referrer.is_some() && request_fee_bps > 0 {
request_fee = referrer_fee_bps(request_fee_bps, fare);
}
if offer_referrer.is_some() && offer_fee_percent > 0 {
offer_fee = referrer_fee_ceiling(offer_fee_percent, fare);
if offer_referrer.is_some() && offer_fee_bps > 0 {
offer_fee = referrer_fee_bps(offer_fee_bps, fare);
}

tx.request_referrer = request_referrer;
Expand Down Expand Up @@ -180,9 +180,10 @@ mod tests {
}

#[test]
fn referrer_fee_ceiling_small_fare() {
assert_eq!(referrer_fee_ceiling(2, 3), 1);
assert_eq!(referrer_fee_ceiling(2, 50), 1);
assert_eq!(referrer_fee_ceiling(2, 100), 2);
fn referrer_fee_bps_floors() {
// 200 bps = 2%, floored (was ceiling under the old percent scheme).
assert_eq!(referrer_fee_bps(200, 3), 0); // floor(0.06) = 0, was ceiling 1
assert_eq!(referrer_fee_bps(200, 50), 1); // floor(1.0) = 1, unchanged
assert_eq!(referrer_fee_bps(200, 100), 2); // floor(2.0) = 2, unchanged
}
}
4 changes: 2 additions & 2 deletions backend/src/explorer/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ pub async fn run_indexer(config: AppConfig) -> Result<(), Box<dyn std::error::Er
pool.clone(),
config.indexer_poll_interval_ms,
config.indexer_start_height,
config.ride_request_referrer_fee_percent,
config.ride_offer_referrer_fee_percent,
config.ride_request_referrer_fee_bps,
config.ride_offer_referrer_fee_bps,
);

let developer_mode = config.developer_mode;
Expand Down
Loading