mirror of
https://github.com/Permissionless-Software-Foundation/psf-bch-api-base.git
synced 2026-09-21 16:52:00 -07:00
3.8 KiB
3.8 KiB
Round-Robin Facilitator Settlement (2026-04-22)
Why this change was made
The previous multi-facilitator behavior relied on @x402/core default precedence selection, which effectively routed verify and settle to the first matching facilitator for a kind (x402Version + network + scheme). This provided fallback, but did not distribute settlement load across facilitators.
The goal of this change was to:
- keep existing verify compatibility and fallback behavior
- distribute settlement requests across configured facilitators
- retain resiliency by failing over if the selected facilitator cannot settle
What was changed
1) New wrapper client for round-robin settlement
Added:
src/lib/x402/round-robin-facilitator-client.js
This wrapper implements the same surface used by x402ResourceServer:
getSupported()verify(paymentPayload, paymentRequirements)settle(paymentPayload, paymentRequirements)
Behavior:
verify()preserves ordered precedence with fallback on errors.settle()performs round-robin rotation per(x402Version, network, scheme).settle()fails over to remaining facilitators in circular order if the selected one fails.getSupported()merges/deduplicateskinds,extensions, andsignersacross facilitators.
2) New facilitator factory
Added:
src/lib/x402/facilitator-client-factory.js
Factory behavior:
- If only one facilitator is active, returns a single
HTTPFacilitatorClientwith strategysingle. - If multiple facilitators are active, returns
RoundRobinFacilitatorClientwith strategyround-robin-failover. - Preserves per-facilitator auth configuration (CDP JWT headers still apply only to facilitators that require auth).
3) Server wiring update
Updated:
bin/server.js
Changes:
- Replaced direct
HTTPFacilitatorClient[]creation/injection with factory-based client creation. x402ResourceServernow receives the factory-produced client (single or wrapper).- Startup logs now include settle strategy marker:
settle strategy: singlesettle strategy: round-robin-failover
4) Documentation update
Updated:
README.md
Added/updated docs for:
ACTIVE_FACILITATORSbehavior under the new strategy- verify vs settle behavior differences
- round-robin configuration example
- quick runtime checks for confirming the strategy is active
Tests added
Added:
test/unit/lib/x402/round-robin-facilitator-client-unit.jstest/unit/lib/x402/facilitator-client-factory-unit.js
Coverage intent:
- settle rotates across 3 facilitators
- settle failover works when selected facilitator errors
- aggregate error is returned when all facilitators fail
- verify still follows ordered precedence/fallback semantics
- merged/deduped
getSupported()data shape is stable - factory returns correct strategy/client type for single vs multi facilitator setups
Validation performed
Targeted unit test run
Command:
npm run test -- --grep "round-robin-facilitator-client|facilitator-client-factory"
Result:
- Passing tests for wrapper + factory (
7 passingat execution time)
Local smoke simulation
Executed a local script using the new wrapper with three mocked facilitators to verify settle rotation sequence.
Observed order:
cdp-txdexter-txpayai-txcdp-txdexter-tx
Operational notes for developers
- Round-robin cursor state is in-memory and process-local; it resets on restart.
- Rotation is keyed by payment kind (
x402Version + network + scheme), not by endpoint or payer. - In multi-facilitator mode, provider default URLs are used per facilitator;
x402_FACILITATOR_URLremains a single-facilitator override. - If one facilitator has intermittent settle failures, traffic still advances via failover and cursor updates on successful settlement.