@peachprojects/aggregator-sdk 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -22,18 +22,19 @@ export declare const API_DEFAULTS: {
22
22
  export declare class ApiClient {
23
23
  private baseUrl;
24
24
  private timeout;
25
+ private extraHeaders;
25
26
  constructor(config?: ApiClientConfig);
26
27
  /**
27
28
  * Find optimal routes via API
28
29
  */
29
- findRoutes(params: {
30
- from: string;
31
- target: string;
32
- amount: bigint;
33
- byAmountIn?: boolean;
34
- depth?: number;
35
- splitCount?: number;
36
- providers?: Provider[];
30
+ findRoutes(params: FindRoutesParams & {
31
+ includeResponseHeaders: true;
32
+ }): Promise<{
33
+ data: ApiFindRouteData;
34
+ responseHeaders: Record<string, string>;
35
+ }>;
36
+ findRoutes(params: FindRoutesParams & {
37
+ includeResponseHeaders?: false;
37
38
  }): Promise<ApiFindRouteData>;
38
39
  /**
39
40
  * Get service status including available providers
@@ -58,6 +59,8 @@ export declare interface ApiClientConfig {
58
59
  baseUrl?: string;
59
60
  /** Request timeout in ms (default: 10000) */
60
61
  timeout?: number;
62
+ /** Extra HTTP headers to send with every request (e.g. `Cookie` for gated staging environments). */
63
+ headers?: Record<string, string>;
61
64
  }
62
65
 
63
66
  /**
@@ -128,6 +131,20 @@ export declare interface ApiFindRouteRequest {
128
131
  */
129
132
  export declare type ApiFindRouteResponse = ApiResponse<ApiFindRouteData>;
130
133
 
134
+ /**
135
+ * PeachRouter fee configuration snapshot served by the aggregator `/router/status`
136
+ * endpoint. Lets clients discover the router address and current fee caps without
137
+ * a separate on-chain read.
138
+ */
139
+ export declare interface ApiPeachRouterConfig {
140
+ /** Deployed PeachRouter contract address the aggregator routes through. */
141
+ router_address: string;
142
+ /** Current upper bound on `CustomFee.feeBps` the router will accept (bps). */
143
+ max_custom_fee_bps: number;
144
+ /** Current upper bound on the protocol's share of the custom fee (bps of the custom fee). */
145
+ max_protocol_cut_bps: number;
146
+ }
147
+
131
148
  /**
132
149
  * Aggregator API response wrapper
133
150
  */
@@ -171,6 +188,8 @@ export declare interface ApiStatusData {
171
188
  providers: string[];
172
189
  /** Chain sync status for each provider */
173
190
  chainflows: ChainflowStatus[];
191
+ /** PeachRouter address + fee-cap configuration. */
192
+ peach_router: ApiPeachRouterConfig;
174
193
  }
175
194
 
176
195
  /**
@@ -203,6 +222,32 @@ export declare interface ChainflowStatus {
203
222
  update_at: number;
204
223
  }
205
224
 
225
+ /**
226
+ * Custom-fee configuration. Pass via `QuoteOptions.customFee` to charge an
227
+ * additional fee on top of the swap output, sent atomically by the on-chain router.
228
+ *
229
+ * Note: the Peach protocol takes a configurable share of this fee (owner-settable,
230
+ * default 20%, capped by the owner-settable `maxProtocolCutBps`). The `feeBps` you
231
+ * set here is the TOTAL fee charged to the user — integrator and protocol split
232
+ * that total according to the router's `protocolCutBps()` at execution time. Use
233
+ * `PeachClient.getRouterConfig()` (or `getProtocolFeeConfig()` for just the split)
234
+ * to read the current values so the UI can display "X bps integrator / Y bps protocol".
235
+ */
236
+ export declare interface CustomFee {
237
+ /** Address that receives the integrator's share of the custom fee (paid in dstToken, or native BNB when dstToken is native). */
238
+ feeAccount: string;
239
+ /** Total custom fee in basis points (1 bps = 0.01%). Must be in `[1, maxCustomFeeBps]` as read from the router. */
240
+ feeBps: number;
241
+ }
242
+
243
+ /**
244
+ * Thrown when a custom-fee configuration is invalid (bad bps or feeAccount).
245
+ * Surfaced before any RPC round-trip so integrators get an actionable error.
246
+ */
247
+ export declare class CustomFeeError extends Error {
248
+ constructor(message: string);
249
+ }
250
+
206
251
  /**
207
252
  * Peach Aggregator SDK Types
208
253
  *
@@ -254,6 +299,17 @@ export declare interface FindFailingStepResult {
254
299
  fullRouteRevertMessage?: string;
255
300
  }
256
301
 
302
+ export declare type FindRoutesParams = {
303
+ from: string;
304
+ target: string;
305
+ amount: bigint;
306
+ byAmountIn?: boolean;
307
+ depth?: number;
308
+ splitCount?: number;
309
+ providers?: Provider[];
310
+ includeResponseHeaders?: boolean;
311
+ };
312
+
257
313
  /**
258
314
  * Check if an address is the native token sentinel address.
259
315
  */
@@ -262,7 +318,28 @@ export declare function isNativeTokenAddress(address: string): boolean;
262
318
  /**
263
319
  * Known DEX providers supported by the SDK.
264
320
  */
265
- export declare type KnownProvider = "PANCAKEV2" | "PANCAKEV3" | "PANCAKE_INFINITY_CL" | "UNISWAPV3" | "UNISWAPV4" | "DODO" | "THENA";
321
+ export declare type KnownProvider = "PANCAKEV2" | "PANCAKEV3" | "PANCAKE_INFINITY_CL" | "UNISWAPV3" | "UNISWAPV4" | "DODO" | "THENA" | "NOMISWAP_STABLE" | "BISWAP" | "APESWAP" | "BABYDOGESWAP" | "BABYSWAP";
322
+
323
+ /**
324
+ * Client-side default cap on the integrator-set custom fee. Mirrors the PeachRouter v2
325
+ * deploy-time initial value of `maxCustomFeeBps` (500 bps = 5%).
326
+ *
327
+ * IMPORTANT: In PeachRouter v2 the cap is an OWNER-SETTABLE state variable in [0, 10_000]
328
+ * bps, not a bytecode constant. This SDK constant is only a convenience default for
329
+ * pre-RPC validation; callers that need the live value must read it via
330
+ * `PeachClient.getRouterConfig()` and validate `customFee.feeBps <= maxCustomFeeBps`.
331
+ */
332
+ export declare const MAX_FEE_BPS = 500;
333
+
334
+ /**
335
+ * Client-side default cap on the protocol's share of the custom fee. Mirrors the
336
+ * PeachRouter v2 deploy-time initial value of `maxProtocolCutBps` (5_000 bps = 50%).
337
+ *
338
+ * IMPORTANT: In PeachRouter v2 this is an OWNER-SETTABLE state variable in [0, 10_000]
339
+ * bps — the owner (Safe multisig) can raise it up to 100%. UIs that want the live
340
+ * value must read it from the chain via `PeachClient.getRouterConfig()`.
341
+ */
342
+ export declare const MAX_PLATFORM_CUT_BPS = 5000;
266
343
 
267
344
  /**
268
345
  * Sentinel address indicating native token (e.g. BNB on BSC).
@@ -337,6 +414,7 @@ export declare class PeachClient {
337
414
  /**
338
415
  * Get quote via API
339
416
  * @throws Error if API client is not configured
417
+ * @throws CustomFeeError if `options.customFee` is malformed
340
418
  */
341
419
  getQuote(params: {
342
420
  srcToken: string;
@@ -344,6 +422,53 @@ export declare class PeachClient {
344
422
  amountIn: bigint;
345
423
  options?: QuoteOptions;
346
424
  }): Promise<Quote>;
425
+ /**
426
+ * Validate custom-fee configuration. Pure / static so callers (tests, custom flows)
427
+ * can reuse it. Throws CustomFeeError on any violation; returns silently for valid input.
428
+ */
429
+ static validateCustomFee(customFee?: CustomFee): void;
430
+ /**
431
+ * Resolve the router address for read methods: argument → quote.routerAddress →
432
+ * config.routerAddress. Throws when none is available so callers never silently
433
+ * read from the zero address.
434
+ */
435
+ private resolveRouterAddress;
436
+ /**
437
+ * Read the protocol-cut configuration from a deployed PeachRouter. Useful for
438
+ * displaying "X bps integrator / Y bps protocol" before the user signs.
439
+ *
440
+ * Values are mutable on-chain — the router owner (Safe) can change them at any
441
+ * time. Re-read before each swap if your UI needs exact numbers on the signing
442
+ * screen.
443
+ *
444
+ * @param routerAddress Optional router address. Defaults to `config.routerAddress`.
445
+ * Pass an explicit address when reading from a different deployment.
446
+ */
447
+ getProtocolFeeConfig(routerAddress?: string): Promise<ProtocolFeeConfig>;
448
+ /**
449
+ * @deprecated Use {@link getProtocolFeeConfig}. Kept as an alias for the pre-v2 name.
450
+ * The returned object now uses the `ProtocolFeeConfig` field names
451
+ * (`protocolFeeReceiver` / `protocolCutBps`).
452
+ */
453
+ getPlatformConfig(routerAddress?: string): Promise<ProtocolFeeConfig>;
454
+ /**
455
+ * Read the full PeachRouter configuration in a single batched call: identity
456
+ * (WETH / owner / pendingOwner), emergency state (`paused`), fee caps
457
+ * (`maxCustomFeeBps`, `maxProtocolCutBps`), and protocol-cut split
458
+ * (`protocolFeeReceiver`, `protocolCutBps`).
459
+ *
460
+ * Intended for:
461
+ * - Verifying a deployment before the UI surfaces swap flows.
462
+ * - Pre-swap checks: reject quotes when `paused == true` or when the requested
463
+ * `customFee.feeBps` exceeds the live `maxCustomFeeBps`.
464
+ * - Showing the integrator / protocol fee split on the signing screen.
465
+ *
466
+ * All fields reflect on-chain state AT READ TIME — the owner (Safe) can mutate
467
+ * caps, the pause flag, and protocol-fee configuration at any time.
468
+ *
469
+ * @param routerAddress Optional router address. Defaults to `config.routerAddress`.
470
+ */
471
+ getRouterConfig(routerAddress?: string): Promise<RouterConfig>;
347
472
  /**
348
473
  * Filter paths by allowed providers, removing paths with disallowed providers
349
474
  * and cascade-removing orphaned paths that depend on removed paths.
@@ -450,6 +575,9 @@ export declare interface PeachConfig {
450
575
  adapters: AdapterConfig[];
451
576
  }
452
577
 
578
+ /** @deprecated Use {@link ProtocolFeeConfig}. Kept as an alias for the pre-v2 name. */
579
+ export declare type PlatformConfig = ProtocolFeeConfig;
580
+
453
581
  export declare interface PoolInfo {
454
582
  address: string;
455
583
  token0: string;
@@ -463,6 +591,18 @@ export declare interface PoolInfo {
463
591
  tick?: number;
464
592
  }
465
593
 
594
+ /**
595
+ * On-chain protocol-cut configuration as read from the deployed PeachRouter.
596
+ * Returned by `PeachClient.getProtocolFeeConfig()` so UIs can display the integrator /
597
+ * protocol split of the custom fee before signing.
598
+ */
599
+ export declare interface ProtocolFeeConfig {
600
+ /** Recipient of the protocol's portion. `ethers.ZeroAddress` means the cut is disabled and the entire custom fee flows to the integrator. */
601
+ protocolFeeReceiver: string;
602
+ /** Protocol's share of the custom fee, in basis points OF THE CUSTOM FEE (not of the swap output). */
603
+ protocolCutBps: number;
604
+ }
605
+
466
606
  export declare enum ProtocolType {
467
607
  PancakeV2 = "PancakeV2",
468
608
  PancakeV3 = "PancakeV3",
@@ -470,7 +610,12 @@ export declare enum ProtocolType {
470
610
  UniswapV3 = "UniswapV3",
471
611
  UniswapV4 = "UniswapV4",
472
612
  Dodo = "Dodo",
473
- Thena = "Thena"
613
+ Thena = "Thena",
614
+ NomiswapStable = "Nomiswap_Stable",
615
+ Biswap = "Biswap",
616
+ Apeswap = "Apeswap",
617
+ BabyDogeSwap = "BabyDogeSwap",
618
+ BabySwap = "BabySwap"
474
619
  }
475
620
 
476
621
  /**
@@ -483,6 +628,10 @@ export declare interface Quote {
483
628
  srcToken: string;
484
629
  dstToken: string;
485
630
  amountIn: bigint;
631
+ /**
632
+ * User-perceived dstToken output AFTER custom fee deduction.
633
+ * The gross figure (before fee) is available at `route.totalAmountOut`.
634
+ */
486
635
  amountOut: bigint;
487
636
  priceImpact: number;
488
637
  route: SplitRoute;
@@ -494,6 +643,21 @@ export declare interface Quote {
494
643
  srcNative?: boolean;
495
644
  /** True when the original dstToken was the native token sentinel address */
496
645
  dstNative?: boolean;
646
+ /**
647
+ * HTTP response headers from the find_routes API call.
648
+ * Only set when `getQuote` was called with `options.includeResponseHeaders: true`.
649
+ */
650
+ responseHeaders?: Record<string, string>;
651
+ /**
652
+ * Custom-fee summary, populated when `getQuote` was called with `options.customFee`.
653
+ * Surfaces what was actually requested (account/bps) and the projected feeAmount in
654
+ * dstToken so the UI can display "X% custom fee → Y dstToken" before signing.
655
+ */
656
+ customFee?: {
657
+ feeAccount: string;
658
+ feeBps: number;
659
+ feeAmount: bigint;
660
+ };
497
661
  }
498
662
 
499
663
  /**
@@ -510,6 +674,18 @@ export declare interface QuoteOptions {
510
674
  providers?: Provider[];
511
675
  /** Transaction deadline in seconds from now (default: 1200 = 20 min) */
512
676
  deadlineSeconds?: number;
677
+ /**
678
+ * When true, the returned `Quote` includes `responseHeaders` with all HTTP response headers from find_routes.
679
+ * Default false — headers are omitted to keep payloads small.
680
+ */
681
+ includeResponseHeaders?: boolean;
682
+ /**
683
+ * Optional custom-fee configuration. When set, an additional fee in basis points
684
+ * is taken from the dstToken output and sent atomically to `customFee.feeAccount`
685
+ * by the on-chain router. The user receives `amountOut * (1 - feeBps/10000)`.
686
+ * Capped at `MAX_FEE_BPS` (500 bps = 5%).
687
+ */
688
+ customFee?: CustomFee;
513
689
  }
514
690
 
515
691
  export declare interface Route {
@@ -521,11 +697,11 @@ export declare interface Route {
521
697
 
522
698
  export declare class RouteDiscovery {
523
699
  private provider;
524
- private config;
525
700
  private v2Factory;
526
701
  private v3Factory;
702
+ private babySwapFactory;
527
703
  private poolCache;
528
- constructor(provider: ethers.Provider, config: PeachConfig);
704
+ constructor(provider: ethers.Provider, _config: PeachConfig);
529
705
  /**
530
706
  * Discover optimal route
531
707
  */
@@ -542,6 +718,10 @@ export declare class RouteDiscovery {
542
718
  * Find V3 pool
543
719
  */
544
720
  private findV3Pool;
721
+ /**
722
+ * Find BabySwap pool (V2 fork, 0.2% fee)
723
+ */
724
+ private findBabySwapPool;
545
725
  /**
546
726
  * Calculate route quotes
547
727
  */
@@ -554,6 +734,10 @@ export declare class RouteDiscovery {
554
734
  * V2 output calculation
555
735
  */
556
736
  private getV2AmountOut;
737
+ /**
738
+ * BabySwap output calculation (V2 fork, 0.2% fee — coefficient 2 in 1000-scale)
739
+ */
740
+ private getBabySwapAmountOut;
557
741
  /**
558
742
  * V3 output estimation (simplified)
559
743
  */
@@ -564,6 +748,33 @@ export declare class RouteDiscovery {
564
748
  clearCache(): void;
565
749
  }
566
750
 
751
+ /**
752
+ * Full PeachRouter configuration snapshot. Returned by `PeachClient.getRouterConfig()`
753
+ * so UIs and integrators can verify router identity, fee caps, pause status, and
754
+ * current protocol-fee split in a single batched read.
755
+ *
756
+ * All fields reflect on-chain state AT READ TIME — the owner (Safe multisig) can
757
+ * mutate caps, the pause flag, and the protocol-fee configuration at any time.
758
+ */
759
+ export declare interface RouterConfig {
760
+ /** Router contract address this snapshot was read from. */
761
+ address: string;
762
+ /** Wrapped native-token address bound at deployment (WBNB on BSC). Immutable. */
763
+ weth: string;
764
+ /** Current owner (Ownable2Step). Typically the Peach Safe multisig. */
765
+ owner: string;
766
+ /** Pending owner from an in-flight `transferOwnership`; `ethers.ZeroAddress` when none. */
767
+ pendingOwner: string;
768
+ /** Emergency pause flag; when true `swap` / `swapETH` revert with `RouterPaused`. */
769
+ paused: boolean;
770
+ /** Active cap on `CustomFee.feeBps`. Owner-settable in [0, 10_000] bps. */
771
+ maxCustomFeeBps: number;
772
+ /** Active cap on `protocolCutBps`. Owner-settable in [0, 10_000] bps. */
773
+ maxProtocolCutBps: number;
774
+ /** Protocol-cut configuration (receiver + bps split of the custom fee). */
775
+ protocolFee: ProtocolFeeConfig;
776
+ }
777
+
567
778
  export declare interface RouteStep {
568
779
  pool: PoolInfo;
569
780
  tokenIn: string;
@@ -641,12 +852,30 @@ export declare interface SwapParams {
641
852
  srcToken: string;
642
853
  dstToken: string;
643
854
  amountIn: bigint;
855
+ /**
856
+ * Minimum dstToken the user is willing to receive AFTER custom fee deduction.
857
+ * Slippage protection applies to the user-perceived amount, not the gross output.
858
+ */
644
859
  amountOutMin: bigint;
645
860
  steps: SwapStep[];
646
861
  intermediateTokens: string[];
647
862
  deadline: bigint;
648
863
  quoteId: string;
864
+ /**
865
+ * Off-chain pre-calculated expected output AFTER custom fee (0 if unused).
866
+ */
649
867
  expectAmountOut: bigint;
868
+ /**
869
+ * Custom-fee recipient address. Ignored when `feeBps == 0`.
870
+ * Use `ethers.ZeroAddress` when no custom fee is configured.
871
+ */
872
+ feeReceiver: string;
873
+ /**
874
+ * Custom fee in basis points, capped at `MAX_FEE_BPS` (500 = 5%).
875
+ * The fee is taken from dstToken output before reaching the user; the on-chain
876
+ * router further splits it between the integrator and the platform.
877
+ */
878
+ feeBps: number;
650
879
  }
651
880
 
652
881
  export declare interface SwapRequest {