@gibs/bridge-sdk 1.17.0 → 1.18.0

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.
Files changed (44) hide show
  1. package/README.md +52 -1
  2. package/dist/cjs/config.d.ts +18 -3
  3. package/dist/cjs/config.js +49 -17
  4. package/dist/cjs/execution.d.ts +17 -4
  5. package/dist/cjs/execution.js +40 -13
  6. package/dist/cjs/index.d.ts +1 -0
  7. package/dist/cjs/index.js +1 -0
  8. package/dist/cjs/prices.d.ts +10 -0
  9. package/dist/cjs/prices.js +54 -2
  10. package/dist/cjs/routing/carrier-provider-key.d.ts +31 -0
  11. package/dist/cjs/routing/carrier-provider-key.js +42 -0
  12. package/dist/cjs/routing/carriers/pulsex.d.ts +50 -25
  13. package/dist/cjs/routing/carriers/pulsex.js +135 -85
  14. package/dist/cjs/routing/index.d.ts +6 -2
  15. package/dist/cjs/routing/index.js +9 -1
  16. package/dist/cjs/routing/route-data.d.ts +47 -5
  17. package/dist/cjs/routing/search/plan-route-data.d.ts +17 -1
  18. package/dist/cjs/routing/search/plan-route-data.js +30 -7
  19. package/dist/cjs/routing/swap-transactions.d.ts +7 -3
  20. package/dist/cjs/routing/swap-transactions.js +6 -4
  21. package/dist/cjs/swap-venues.d.ts +43 -0
  22. package/dist/cjs/swap-venues.js +29 -0
  23. package/dist/config.d.ts +18 -3
  24. package/dist/config.js +48 -16
  25. package/dist/execution.d.ts +17 -4
  26. package/dist/execution.js +41 -14
  27. package/dist/index.d.ts +1 -0
  28. package/dist/index.js +1 -0
  29. package/dist/prices.d.ts +10 -0
  30. package/dist/prices.js +52 -1
  31. package/dist/routing/carrier-provider-key.d.ts +31 -0
  32. package/dist/routing/carrier-provider-key.js +37 -0
  33. package/dist/routing/carriers/pulsex.d.ts +50 -25
  34. package/dist/routing/carriers/pulsex.js +133 -84
  35. package/dist/routing/index.d.ts +6 -2
  36. package/dist/routing/index.js +3 -1
  37. package/dist/routing/route-data.d.ts +47 -5
  38. package/dist/routing/search/plan-route-data.d.ts +17 -1
  39. package/dist/routing/search/plan-route-data.js +30 -7
  40. package/dist/routing/swap-transactions.d.ts +7 -3
  41. package/dist/routing/swap-transactions.js +7 -5
  42. package/dist/swap-venues.d.ts +43 -0
  43. package/dist/swap-venues.js +24 -0
  44. package/package.json +3 -3
@@ -1,34 +1,50 @@
1
1
  import { type Hex } from 'viem';
2
2
  import type { PublicClient } from 'viem';
3
+ import { type SwapVenue, type SwapVenues } from '../../swap-venues.js';
3
4
  import { type AssetNode, type HopEdge, type PlannedHop } from '../search/graph.js';
4
5
  import type { CarrierAskAnswer, CarrierExactResult } from './ask-answer.js';
5
6
  /**
6
- * One PulseX deployment a swap can execute on: the router the reader signs
7
- * and the factory whose pools that router trades against. A Uniswap-V2-style
7
+ * One swap deployment a swap can execute on: the router the reader signs and
8
+ * the factory whose pools that router trades against. A Uniswap-V2-style
8
9
  * router resolves every pool through its OWN factory, so one router call can
9
10
  * only ever touch that one deployment's pools — a path can never mix them.
11
+ *
12
+ * Same type as {@link SwapVenue}; the old name stays for existing callers.
10
13
  */
11
- export type PulseXVenue = {
12
- readonly router: Hex;
13
- readonly factory: Hex;
14
- };
14
+ export type PulseXVenue = SwapVenue;
15
15
  /**
16
- * Every PulseX deployment on PulseChain, V1 first: `uniV2Routers` paired with
17
- * `uniV2Factories` by index. Each factory is the router's own
18
- * `router.factory()` read on chain — see `uniV2Factories`'s own doc in
19
- * `config.ts`. A router with no recorded factory is left out, because its
20
- * pools cannot be read.
16
+ * Every PulseX deployment on PulseChain, V1 first: the PulseChain entry of
17
+ * {@link defaultSwapVenues}. Frozen. It lists the DEFAULTS only — a carrier
18
+ * built with its own `venues` offers those instead.
21
19
  */
22
20
  export declare const pulseXVenues: readonly PulseXVenue[];
23
21
  /**
24
- * The router a PulseX edge must be signed on — the one its figure was quoted
25
- * against. Reads the edge's own {@link HopEdge.venue}; an edge with none is a
26
- * V1 edge (see {@link defaultPulseXVenue}).
22
+ * The {@link SwapVenue} a swap edge runs on: the one its figure was quoted
23
+ * against. Reads the edge's own {@link HopEdge.venue}; an edge with none runs
24
+ * on the FIRST venue of its chain (V1 for PulseX) — every swap edge built
25
+ * before venues existed was quoted and signed there, and the same-chain swap
26
+ * sender's own hand-built edge still is.
27
+ *
28
+ * NEVER FALLS BACK TO ANOTHER CHAIN OR ANOTHER ROUTER. An edge that names a
29
+ * router `venues` does not list gets null, so the caller can refuse it.
30
+ *
31
+ * @param venues - the venues the caller allows
32
+ * @param edge - the edge to sign; `from` names the chain, and defaults to PulseChain when absent
33
+ * @returns the venue, or null when the edge is not a swap edge or names a router that is not in `venues`
34
+ */
35
+ export declare const venueForEdge: (venues: SwapVenues, edge: Pick<HopEdge, "carrier" | "venue"> & {
36
+ readonly from?: Pick<AssetNode, "chainId">;
37
+ }) => SwapVenue | null;
38
+ /**
39
+ * The router a PulseX edge must be signed on, judged against the DEFAULT
40
+ * venues only. Prefer {@link venueForEdge} with the venues your host passes.
27
41
  *
28
42
  * @param edge - the edge to sign
29
- * @returns the router, or null when the edge is not a PulseX edge or names a venue that is not a known PulseX router
43
+ * @returns the router, or null when the edge is not a swap edge or names a router that is not a default
30
44
  */
31
- export declare const pulseXRouterForEdge: (edge: Pick<HopEdge, "carrier" | "venue">) => Hex | null;
45
+ export declare const pulseXRouterForEdge: (edge: Pick<HopEdge, "carrier" | "venue"> & {
46
+ readonly from?: Pick<AssetNode, "chainId">;
47
+ }) => Hex | null;
32
48
  /**
33
49
  * The fixed Wrapped-PLS path from `from` to `to` — `[from, WPLS, to]`, or
34
50
  * `[from, to]` when one side is WPLS — or null when both ends resolve to the
@@ -78,9 +94,10 @@ export type PulseXPathStep = {
78
94
  *
79
95
  * @param amountIn - the amount entering the first pool
80
96
  * @param steps - the pools in order of travel
97
+ * @param feeBasisPoints - the venue's swap fee in basis points; PulseX's 29 when omitted
81
98
  * @returns the amount leaving the last pool; 0 when any pool cannot pay out
82
99
  */
83
- export declare const amountOutAlongPath: (amountIn: bigint, steps: readonly PulseXPathStep[]) => bigint;
100
+ export declare const amountOutAlongPath: (amountIn: bigint, steps: readonly PulseXPathStep[], feeBasisPoints?: number) => bigint;
84
101
  /**
85
102
  * How far a trade's executed rate falls below the marginal (near-spot) rate,
86
103
  * in percent. The marginal rate is a tiny reference trade through the same
@@ -110,12 +127,12 @@ export type CreatePulseXCarrierOptions = {
110
127
  * in the edge's `to` token's base units. Returns null when the path has no
111
128
  * liquidity.
112
129
  *
113
- * MUST READ THE EDGE'S OWN ROUTER ({@link pulseXRouterForEdge}). A V2 edge
130
+ * MUST READ THE EDGE'S OWN ROUTER ({@link venueForEdge}). A V2 edge
114
131
  * answered from V1 would carry V1's figure into a V2 signature.
115
132
  */
116
133
  readonly readAmountOut: (edge: HopEdge, inputAmount: bigint) => Promise<bigint | null>;
117
134
  /**
118
- * Returns a PulseChain client, for {@link Carrier.prepare}'s own batched
135
+ * Returns a client for a chain, for {@link Carrier.prepare}'s own batched
119
136
  * reserve reads — never called by `ask`, which keeps using
120
137
  * {@link readAmountOut} unchanged.
121
138
  *
@@ -123,17 +140,25 @@ export type CreatePulseXCarrierOptions = {
123
140
  * field for why: a host that has not wired this yet gets the carrier's
124
141
  * original behavior, `prepare` a no-op and `exact` always `null`.
125
142
  *
126
- * @param chainId - always {@link pulsechainChainId} — PulseX runs nowhere else
143
+ * @param chainId - a chain that has swap venues
127
144
  * @returns a client, or null when this host has none
128
145
  */
129
146
  readonly clientForChain?: (chainId: number) => PublicClient | null;
130
147
  /**
131
- * The PulseX routers this host can SIGN on. The carrier offers an edge on
132
- * each, and only on these: an edge is always signed on the router it was
133
- * quoted against ({@link pulseXRouterForEdge}), so a router the host cannot
134
- * sign on must never be quoted either.
148
+ * The swap venues to offer. Merged over {@link defaultSwapVenues} by
149
+ * {@link resolveSwapVenues}: a chain named here REPLACES that chain's
150
+ * default list, a chain left out keeps its defaults, and an empty list
151
+ * switches swaps off on that chain. A venue on ANY chain builds swap edges
152
+ * there.
153
+ */
154
+ readonly venues?: SwapVenues;
155
+ /**
156
+ * Narrows the offered venues to these routers. An edge is always signed on
157
+ * the router it was quoted against ({@link venueForEdge}), so a router the
158
+ * host cannot sign on must never be quoted either. A router that is in no
159
+ * offered venue is a configuration error and throws at construction.
135
160
  *
136
- * Defaults to every known venue ({@link pulseXVenues}: V1 and V2).
161
+ * Defaults to every offered venue.
137
162
  */
138
163
  readonly routers?: readonly Hex[];
139
164
  };
@@ -33,13 +33,14 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.createPulseXCarrier = exports.priceImpactAgainstMarginal = exports.amountOutAlongPath = exports.pulseXSwapPathForHop = exports.pulseXWrappedNativePath = exports.pulseXRouterForEdge = exports.pulseXVenues = void 0;
36
+ exports.createPulseXCarrier = exports.priceImpactAgainstMarginal = exports.amountOutAlongPath = exports.pulseXSwapPathForHop = exports.pulseXWrappedNativePath = exports.pulseXRouterForEdge = exports.venueForEdge = exports.pulseXVenues = void 0;
37
37
  const multicall_1 = require("@gibs/common/multicall");
38
38
  const viem_1 = require("viem");
39
39
  const abis = __importStar(require("../../abis.js"));
40
40
  const chains_js_1 = require("../../chains.js");
41
41
  const config_js_1 = require("../../config.js");
42
42
  const ecosystems_js_1 = require("../../ecosystems.js");
43
+ const swap_venues_js_1 = require("../../swap-venues.js");
43
44
  const providers_js_1 = require("../providers.js");
44
45
  const producers_js_1 = require("../producers.js");
45
46
  const graph_js_1 = require("../search/graph.js");
@@ -54,58 +55,75 @@ const pulsex_paths_js_1 = require("./pulsex-paths.js");
54
55
  * See `omnibridge.ts`'s head doc for why this returns a plain object shaped
55
56
  * like `Carrier` rather than importing that type.
56
57
  */
57
- /** WPLS, the wrapped-native intermediary {@link pulseXConversionSwapPath} routes conversions through. */
58
- const wplsAddress = config_js_1.nativeAssetOut[config_js_1.Chains.PLS];
59
- /** The hub addresses every candidate path is built from — see {@link pulseXHubTokens}. */
58
+ /** The hub addresses every candidate path on PulseChain is built from — see {@link pulseXHubTokens}. */
60
59
  const hubAddresses = pulsex_paths_js_1.pulseXHubTokens.map((hub) => hub.address);
61
60
  /**
62
- * Every PulseX deployment on PulseChain, V1 first: `uniV2Routers` paired with
63
- * `uniV2Factories` by index. Each factory is the router's own
64
- * `router.factory()` read on chain — see `uniV2Factories`'s own doc in
65
- * `config.ts`. A router with no recorded factory is left out, because its
66
- * pools cannot be read.
61
+ * The wrapped-native token a chain's swaps route through, or undefined when
62
+ * this package does not know one for the chain. Without it a path on that
63
+ * chain can only be direct.
64
+ *
65
+ * @param chainId - the numeric chain id
67
66
  */
68
- exports.pulseXVenues = (config_js_1.uniV2Routers[config_js_1.Chains.PLS] ?? []).flatMap((router, index) => {
69
- const factory = config_js_1.uniV2Factories[config_js_1.Chains.PLS]?.[index];
70
- return factory === undefined ? [] : [{ router: (0, viem_1.getAddress)(router), factory: (0, viem_1.getAddress)(factory) }];
71
- });
67
+ const wrappedNativeFor = (chainId) => {
68
+ const wrapped = config_js_1.nativeAssetOut[(0, config_js_1.toChain)(chainId)];
69
+ return wrapped === undefined ? undefined : (0, viem_1.getAddress)(wrapped);
70
+ };
72
71
  /**
73
- * The venue an edge with no {@link HopEdge.venue} runs on: V1, index 0. Every
74
- * PulseX edge built before venues existed was quoted and signed on V1 — the
75
- * same-chain swap sender's own hand-built edge still is — so this keeps that
76
- * meaning rather than guessing a new one.
72
+ * The hub tokens a path on `chainId` may pass through. PulseChain has the
73
+ * full list; any other chain has only its wrapped-native token, because this
74
+ * package knows no other hubs.
77
75
  */
78
- const defaultPulseXVenue = exports.pulseXVenues[0];
76
+ const hubsFor = (chainId) => {
77
+ if (chainId === producers_js_1.pulsechainChainId)
78
+ return hubAddresses;
79
+ const wrapped = wrappedNativeFor(chainId);
80
+ return wrapped === undefined ? [] : [wrapped];
81
+ };
79
82
  /**
80
- * The router a PulseX edge must be signed on — the one its figure was quoted
81
- * against. Reads the edge's own {@link HopEdge.venue}; an edge with none is a
82
- * V1 edge (see {@link defaultPulseXVenue}).
83
- *
84
- * @param edge - the edge to sign
85
- * @returns the router, or null when the edge is not a PulseX edge or names a venue that is not a known PulseX router
83
+ * Every PulseX deployment on PulseChain, V1 first: the PulseChain entry of
84
+ * {@link defaultSwapVenues}. Frozen. It lists the DEFAULTS only — a carrier
85
+ * built with its own `venues` offers those instead.
86
86
  */
87
- const pulseXRouterForEdge = (edge) => pulseXVenueForEdge(edge)?.router ?? null;
88
- exports.pulseXRouterForEdge = pulseXRouterForEdge;
87
+ exports.pulseXVenues = config_js_1.defaultSwapVenues[producers_js_1.pulsechainChainId] ?? [];
89
88
  /**
90
- * The {@link PulseXVenue} a PulseX edge runs on — see {@link pulseXRouterForEdge}.
89
+ * The {@link SwapVenue} a swap edge runs on: the one its figure was quoted
90
+ * against. Reads the edge's own {@link HopEdge.venue}; an edge with none runs
91
+ * on the FIRST venue of its chain (V1 for PulseX) — every swap edge built
92
+ * before venues existed was quoted and signed there, and the same-chain swap
93
+ * sender's own hand-built edge still is.
94
+ *
95
+ * NEVER FALLS BACK TO ANOTHER CHAIN OR ANOTHER ROUTER. An edge that names a
96
+ * router `venues` does not list gets null, so the caller can refuse it.
91
97
  *
92
- * @param edge - the edge
93
- * @returns the venue, or null when there is none
98
+ * @param venues - the venues the caller allows
99
+ * @param edge - the edge to sign; `from` names the chain, and defaults to PulseChain when absent
100
+ * @returns the venue, or null when the edge is not a swap edge or names a router that is not in `venues`
94
101
  */
95
- const pulseXVenueForEdge = (edge) => {
102
+ const venueForEdge = (venues, edge) => {
96
103
  if (edge.carrier !== 'PulseX')
97
104
  return null;
105
+ const chainId = edge.from?.chainId ?? producers_js_1.pulsechainChainId;
98
106
  if (edge.venue === undefined)
99
- return defaultPulseXVenue ?? null;
100
- const venue = edge.venue;
101
- return exports.pulseXVenues.find((candidate) => (0, ecosystems_js_1.sameAddress)(candidate.router, venue, 'evm')) ?? null;
107
+ return venues[chainId]?.[0] ?? null;
108
+ return (0, swap_venues_js_1.findSwapVenue)(venues, chainId, edge.venue);
102
109
  };
110
+ exports.venueForEdge = venueForEdge;
103
111
  /**
104
- * A node's own address for a PulseX pool lookup: native PLS (the zero
105
- * address) is not a token the router or its factory ever holds a pool for —
106
- * only Wrapped PLS is — so a native node resolves to {@link wplsAddress}
112
+ * The router a PulseX edge must be signed on, judged against the DEFAULT
113
+ * venues only. Prefer {@link venueForEdge} with the venues your host passes.
114
+ *
115
+ * @param edge - the edge to sign
116
+ * @returns the router, or null when the edge is not a swap edge or names a router that is not a default
117
+ */
118
+ const pulseXRouterForEdge = (edge) => (0, exports.venueForEdge)(config_js_1.defaultSwapVenues, edge)?.router ?? null;
119
+ exports.pulseXRouterForEdge = pulseXRouterForEdge;
120
+ /**
121
+ * A node's own address for a pool lookup: native (the zero address) is not a
122
+ * token the router or its factory ever holds a pool for — only the chain's
123
+ * wrapped-native token is — so a native node resolves to that wrapped token
107
124
  * before it ever reaches {@link pulseXConversionSwapPath}. Every other node
108
- * is unchanged.
125
+ * is unchanged. A chain with no known wrapped-native token leaves a native
126
+ * node as it is; it has no pool, so no path prices.
109
127
  *
110
128
  * MIRRORS `useRouteSearch.ts`'s `quotePathAddress` (the UI's async `ask`
111
129
  * already resolves native this way through that function) — this is the
@@ -113,9 +131,9 @@ const pulseXVenueForEdge = (edge) => {
113
131
  * UI's `readAmountOut` at all; see {@link pulseXCandidatePaths}'s own doc.
114
132
  *
115
133
  * @param node - the node to resolve
116
- * @returns the node's own address, or {@link wplsAddress} for native PLS
134
+ * @returns the node's own address, or its chain's wrapped-native address for a native node
117
135
  */
118
- const poolTokenAddress = (node) => ((0, ecosystems_js_1.sameAddress)(node.address, viem_1.zeroAddress, 'evm') ? wplsAddress : node.address);
136
+ const poolTokenAddress = (node) => (0, ecosystems_js_1.sameAddress)(node.address, viem_1.zeroAddress, 'evm') ? (wrappedNativeFor(node.chainId) ?? viem_1.zeroAddress) : node.address;
119
137
  /**
120
138
  * The fixed Wrapped-PLS path from `from` to `to` — `[from, WPLS, to]`, or
121
139
  * `[from, to]` when one side is WPLS — or null when both ends resolve to the
@@ -140,7 +158,8 @@ const pulseXWrappedNativePath = (from, to) => {
140
158
  const toAddress = poolTokenAddress(to);
141
159
  if ((0, ecosystems_js_1.sameAddress)(fromAddress, toAddress, 'evm'))
142
160
  return null;
143
- return (0, providers_js_1.pulseXConversionSwapPath)(fromAddress, toAddress, wplsAddress);
161
+ const wrappedNative = wrappedNativeFor(from.chainId);
162
+ return wrappedNative === undefined ? [fromAddress, toAddress] : (0, providers_js_1.pulseXConversionSwapPath)(fromAddress, toAddress, wrappedNative);
144
163
  };
145
164
  exports.pulseXWrappedNativePath = pulseXWrappedNativePath;
146
165
  /**
@@ -160,21 +179,27 @@ const pulseXCandidatePaths = (from, to) => {
160
179
  const toAddress = poolTokenAddress(to);
161
180
  if ((0, ecosystems_js_1.sameAddress)(fromAddress, toAddress, 'evm'))
162
181
  return [];
163
- return (0, pulsex_paths_js_1.candidatePulseXPaths)({ from: fromAddress, to: toAddress, wrappedNative: wplsAddress, hubs: hubAddresses });
182
+ const wrappedNative = wrappedNativeFor(from.chainId);
183
+ // No known wrapped-native token: the direct pool is the only path.
184
+ if (wrappedNative === undefined)
185
+ return [[fromAddress, toAddress]];
186
+ return (0, pulsex_paths_js_1.candidatePulseXPaths)({ from: fromAddress, to: toAddress, wrappedNative, hubs: hubsFor(from.chainId) });
164
187
  };
165
188
  /**
166
- * Whether PulseX can carry funds directly from `from` to `to`: both must be
167
- * Ethereum-Virtual-Machine tokens on PulseChain itself — PulseX runs only on
168
- * PulseChain, never on an entry chain — that resolve to two different pool
169
- * tokens, so there is at least one path to price.
189
+ * Whether a swap venue in `venues` can carry funds directly from `from` to
190
+ * `to`: both must be Ethereum-Virtual-Machine tokens on the SAME chain, that
191
+ * chain must have at least one venue, and the two must resolve to different
192
+ * pool tokens, so there is at least one path to price.
170
193
  *
171
194
  * NO TOKEN ALLOWLIST IS CONSULTED, on purpose: whether a pool exists is the
172
195
  * reserve read's question, answered in `prepare`, not this one's.
173
196
  */
174
- const pulseXCarries = (from, to) => {
197
+ const pulseXCarries = (venues, from, to) => {
175
198
  if (from.ecosystem !== 'evm' || to.ecosystem !== 'evm')
176
199
  return false;
177
- if (from.chainId !== producers_js_1.pulsechainChainId || to.chainId !== producers_js_1.pulsechainChainId)
200
+ if (from.chainId !== to.chainId)
201
+ return false;
202
+ if ((venues[from.chainId] ?? []).length === 0)
178
203
  return false;
179
204
  return pulseXCandidatePaths(from, to).length > 0;
180
205
  };
@@ -212,8 +237,9 @@ const pulseXSwapPathForHop = (hop) => {
212
237
  };
213
238
  exports.pulseXSwapPathForHop = pulseXSwapPathForHop;
214
239
  /**
215
- * PulseX's own constant-product swap fee, as a numerator over
216
- * {@link PULSEX_FEE_DENOMINATOR} — the SAME `getAmountOut` formula every
240
+ * PulseX's own constant-product swap fee in basis points (29 of 10000, a
241
+ * numerator of 9971) — the default for {@link amountOutAlongPath}; a
242
+ * venue carries its own `feeBasisPoints`. The SAME `getAmountOut` formula every
217
243
  * Uniswap-V2-style router uses: `amountOut = floor(amountIn * feeNumerator *
218
244
  * reserveOut / (reserveIn * feeDenominator + amountIn * feeNumerator))`.
219
245
  *
@@ -226,16 +252,16 @@ exports.pulseXSwapPathForHop = pulseXSwapPathForHop;
226
252
  * this claim against live chain data rather than trusting the arithmetic
227
253
  * alone.
228
254
  */
229
- const PULSEX_FEE_NUMERATOR = 9971n;
230
- /** The denominator {@link PULSEX_FEE_NUMERATOR} is a fraction of. */
231
- const PULSEX_FEE_DENOMINATOR = 10000n;
255
+ const PULSEX_FEE_BASIS_POINTS = 29;
256
+ /** Basis points in a whole: the denominator of every venue's fee. */
257
+ const BASIS_POINTS_DENOMINATOR = 10000n;
232
258
  /** The minimal read-only factory ABI `prepare` needs — just enough to resolve a pool's address from its two tokens. */
233
259
  const univ2FactoryAbi = (0, viem_1.parseAbi)([
234
260
  'function getPair(address tokenA, address tokenB) external view returns (address pair)',
235
261
  ]);
236
262
  /**
237
263
  * The Uniswap-V2-style constant-product `getAmountOut`, applied with
238
- * {@link PULSEX_FEE_NUMERATOR}. Reproduces the router's own on-chain formula
264
+ * the venue's fee. Reproduces the router's own on-chain formula
239
265
  * exactly — see `pulsex-carrier.fork.test.ts` — so PRICE IMPACT IS ALREADY
240
266
  * IN HERE: this is the same nonlinear function the router evaluates, not a
241
267
  * flat-fee approximation with an impact correction bolted on afterward.
@@ -243,14 +269,15 @@ const univ2FactoryAbi = (0, viem_1.parseAbi)([
243
269
  * @param amountIn - the input amount, in `reserveIn`'s token's base units
244
270
  * @param reserveIn - the pool's reserve of the input token
245
271
  * @param reserveOut - the pool's reserve of the output token
272
+ * @param feeBasisPoints - the venue's swap fee, in basis points
246
273
  * @returns the output amount, in `reserveOut`'s token's base units; 0 when either reserve is 0
247
274
  */
248
- const constantProductAmountOut = (amountIn, reserveIn, reserveOut) => {
275
+ const constantProductAmountOut = (amountIn, reserveIn, reserveOut, feeBasisPoints) => {
249
276
  if (reserveIn <= 0n || reserveOut <= 0n || amountIn <= 0n)
250
277
  return 0n;
251
- const amountInWithFee = amountIn * PULSEX_FEE_NUMERATOR;
278
+ const amountInWithFee = amountIn * (BASIS_POINTS_DENOMINATOR - BigInt(feeBasisPoints));
252
279
  const numerator = amountInWithFee * reserveOut;
253
- const denominator = reserveIn * PULSEX_FEE_DENOMINATOR + amountInWithFee;
280
+ const denominator = reserveIn * BASIS_POINTS_DENOMINATOR + amountInWithFee;
254
281
  return numerator / denominator;
255
282
  };
256
283
  /**
@@ -259,9 +286,10 @@ const constantProductAmountOut = (amountIn, reserveIn, reserveOut) => {
259
286
  *
260
287
  * @param amountIn - the amount entering the first pool
261
288
  * @param steps - the pools in order of travel
289
+ * @param feeBasisPoints - the venue's swap fee in basis points; PulseX's 29 when omitted
262
290
  * @returns the amount leaving the last pool; 0 when any pool cannot pay out
263
291
  */
264
- const amountOutAlongPath = (amountIn, steps) => steps.reduce((runningAmount, step) => constantProductAmountOut(runningAmount, step.reserveIn, step.reserveOut), amountIn);
292
+ const amountOutAlongPath = (amountIn, steps, feeBasisPoints = PULSEX_FEE_BASIS_POINTS) => steps.reduce((runningAmount, step) => constantProductAmountOut(runningAmount, step.reserveIn, step.reserveOut, feeBasisPoints), amountIn);
265
293
  exports.amountOutAlongPath = amountOutAlongPath;
266
294
  /**
267
295
  * How far a trade's executed rate falls below the marginal (near-spot) rate,
@@ -299,7 +327,7 @@ const poolKey = (tokenA, tokenB) => {
299
327
  return `${lower}|${higher}`;
300
328
  };
301
329
  /** The key one venue's pool is stored under: the same two tokens on V1 and on V2 are two different pools with two different reserves. */
302
- const venuePoolKey = (venue, tokenA, tokenB) => `${venue.factory.toLowerCase()}|${poolKey(tokenA, tokenB)}`;
330
+ const venuePoolKey = (venue, tokenA, tokenB) => `${venue.chainId}|${venue.factory.toLowerCase()}|${poolKey(tokenA, tokenB)}`;
303
331
  /** Every consecutive (tokenIn, tokenOut) hop a PulseX swap path implies. */
304
332
  const hopsAlongPath = (path) => path.slice(0, -1).map((tokenIn, index) => [tokenIn, path[index + 1]]);
305
333
  /**
@@ -359,16 +387,36 @@ const stepsAlongPath = (options) => {
359
387
  */
360
388
  const preparePulseXReserves = async ({ nodes, venues, clientForChain, }) => {
361
389
  const reservesByPoolKey = new Map();
362
- const client = clientForChain(producers_js_1.pulsechainChainId);
363
- if (client === null || venues.length === 0)
390
+ const chainIds = Object.keys(venues)
391
+ .map(Number)
392
+ .filter((chainId) => (venues[chainId] ?? []).length > 0);
393
+ for (const chainId of chainIds) {
394
+ const chainReserves = await preparePulseXReservesOnChain({ nodes, chainId, venues, clientForChain });
395
+ for (const [key, reserves] of chainReserves)
396
+ reservesByPoolKey.set(key, reserves);
397
+ }
398
+ return reservesByPoolKey;
399
+ };
400
+ /**
401
+ * One chain's share of {@link preparePulseXReserves}: two multicalls, the
402
+ * `getPair` reads and then the `getReserves` reads, over every venue of the
403
+ * chain. A chain with no client, or with no chain description to multicall
404
+ * against, reads nothing.
405
+ */
406
+ const preparePulseXReservesOnChain = async ({ nodes, chainId, venues, clientForChain, }) => {
407
+ const reservesByPoolKey = new Map();
408
+ const client = clientForChain(chainId);
409
+ const knownChain = chains_js_1.chainsMetadata[(0, config_js_1.toChain)(chainId)];
410
+ const chain = knownChain ?? client?.chain;
411
+ if (client === null || chain === undefined)
364
412
  return reservesByPoolKey;
365
- const pulsechainNodes = nodes.filter((node) => node.ecosystem === 'evm' && node.chainId === producers_js_1.pulsechainChainId);
413
+ const chainNodes = nodes.filter((node) => node.ecosystem === 'evm' && node.chainId === chainId);
366
414
  const poolTokenPairs = new Map();
367
- for (const from of pulsechainNodes) {
368
- for (const to of pulsechainNodes) {
415
+ for (const from of chainNodes) {
416
+ for (const to of chainNodes) {
369
417
  if ((0, graph_js_1.assetNodeKey)(from) === (0, graph_js_1.assetNodeKey)(to))
370
418
  continue;
371
- if (!pulseXCarries(from, to))
419
+ if (!pulseXCarries(venues, from, to))
372
420
  continue;
373
421
  for (const path of pulseXCandidatePaths(from, to)) {
374
422
  for (const [tokenIn, tokenOut] of hopsAlongPath(path)) {
@@ -379,14 +427,14 @@ const preparePulseXReserves = async ({ nodes, venues, clientForChain, }) => {
379
427
  }
380
428
  if (poolTokenPairs.size === 0)
381
429
  return reservesByPoolKey;
382
- const poolQueries = venues.flatMap((venue) => Array.from(poolTokenPairs.values()).map(([tokenIn, tokenOut]) => ({
430
+ const poolQueries = (venues[chainId] ?? []).flatMap((venue) => Array.from(poolTokenPairs.values()).map(([tokenIn, tokenOut]) => ({
383
431
  key: venuePoolKey(venue, tokenIn, tokenOut),
384
432
  factory: venue.factory,
385
433
  tokenIn,
386
434
  tokenOut,
387
435
  })));
388
436
  const factoryResults = await (0, multicall_1.multicallRead)({
389
- chain: chains_js_1.chainsMetadata[(0, config_js_1.toChain)(producers_js_1.pulsechainChainId)],
437
+ chain,
390
438
  client,
391
439
  abi: univ2FactoryAbi,
392
440
  calls: poolQueries.map((query) => ({
@@ -411,7 +459,7 @@ const preparePulseXReserves = async ({ nodes, venues, clientForChain, }) => {
411
459
  return reservesByPoolKey;
412
460
  const reservePoolKeys = Array.from(pairAddressByPoolKey.keys());
413
461
  const reserveResults = await (0, multicall_1.multicallRead)({
414
- chain: chains_js_1.chainsMetadata[(0, config_js_1.toChain)(producers_js_1.pulsechainChainId)],
462
+ chain,
415
463
  client,
416
464
  abi: abis.pair,
417
465
  calls: reservePoolKeys.map((key) => ({
@@ -436,22 +484,24 @@ const preparePulseXReserves = async ({ nodes, venues, clientForChain, }) => {
436
484
  return reservesByPoolKey;
437
485
  };
438
486
  /**
439
- * The venues a carrier offers: every known venue, or only the routers the
440
- * host names. A named router that is not a known PulseX router is a
441
- * configuration error, thrown at construction rather than offered silently.
487
+ * The venues a carrier offers: every venue in `venues`, or only the routers
488
+ * the host names. A named router that is in no venue is a configuration
489
+ * error, thrown at construction rather than offered silently.
442
490
  *
491
+ * @param venues - the resolved venues
443
492
  * @param routers - the routers the host can sign on, or undefined for all
444
- * @returns the venues, in {@link pulseXVenues} order
493
+ * @returns the venues, in their original order
445
494
  */
446
- const selectPulseXVenues = (routers) => {
495
+ const selectPulseXVenues = (venues, routers) => {
447
496
  if (routers === undefined)
448
- return exports.pulseXVenues;
497
+ return venues;
498
+ const named = (venue) => routers.some((router) => (0, ecosystems_js_1.sameAddress)(venue.router, router, 'evm'));
449
499
  for (const router of routers) {
450
- if (!exports.pulseXVenues.some((venue) => (0, ecosystems_js_1.sameAddress)(venue.router, router, 'evm'))) {
451
- throw new Error(`createPulseXCarrier: ${router} is not a known PulseX router on PulseChain`);
452
- }
500
+ const offered = Object.values(venues).some((list) => list.some((venue) => (0, ecosystems_js_1.sameAddress)(venue.router, router, 'evm')));
501
+ if (!offered)
502
+ throw new Error(`createPulseXCarrier: ${router} is not a known PulseX router in the offered swap venues`);
453
503
  }
454
- return exports.pulseXVenues.filter((venue) => routers.some((router) => (0, ecosystems_js_1.sameAddress)(venue.router, router, 'evm')));
504
+ return Object.freeze(Object.fromEntries(Object.entries(venues).map(([chainId, list]) => [chainId, list.filter(named)])));
455
505
  };
456
506
  /**
457
507
  * Builds the PulseX conversion swap as a plug-in carrier.
@@ -461,16 +511,16 @@ const selectPulseXVenues = (routers) => {
461
511
  */
462
512
  const createPulseXCarrier = (options) => {
463
513
  const { readAmountOut, clientForChain } = options;
464
- const venues = selectPulseXVenues(options.routers);
514
+ const venues = selectPulseXVenues((0, swap_venues_js_1.resolveSwapVenues)(options.venues), options.routers);
465
515
  // ONE EDGE PER VENUE. Each names its router as its `venue`, so the search
466
516
  // quotes and ranks V1 and V2 as two separate hops and the better one wins
467
517
  // on its own figure — and the winner is signed on the router it names.
468
518
  const edgesFrom = (from, to) => {
469
519
  if ((0, graph_js_1.assetNodeKey)(from) === (0, graph_js_1.assetNodeKey)(to))
470
520
  return [];
471
- if (!pulseXCarries(from, to))
521
+ if (!pulseXCarries(venues, from, to))
472
522
  return [];
473
- return venues.map((venue) => ({
523
+ return (venues[from.chainId] ?? []).map((venue) => ({
474
524
  carrier: 'PulseX',
475
525
  from,
476
526
  to,
@@ -506,19 +556,19 @@ const createPulseXCarrier = (options) => {
506
556
  reservesByPoolKey = await preparePulseXReserves({ nodes, venues, clientForChain });
507
557
  };
508
558
  const exact = (edge, amountIn) => {
509
- if (!pulseXCarries(edge.from, edge.to))
559
+ if (!pulseXCarries(venues, edge.from, edge.to))
510
560
  return null;
511
561
  // Quoted on the edge's OWN venue — the router it will be signed on — and
512
562
  // only on a venue this carrier offers.
513
- const venue = pulseXVenueForEdge(edge);
514
- if (venue === null || !venues.includes(venue))
563
+ const venue = (0, exports.venueForEdge)(venues, edge);
564
+ if (venue === null)
515
565
  return null;
516
566
  // EVERY CANDIDATE PATH IS PRICED, AND THE BEST ONE WINS. A path with a
517
567
  // pool `prepare` never found is left out — the same as a router call
518
568
  // that would revert — and a path that pays out nothing is never picked.
519
569
  const quotes = pulseXCandidatePaths(edge.from, edge.to).flatMap((path) => {
520
570
  const steps = stepsAlongPath({ venue, path, reservesByPoolKey });
521
- return steps === null ? [] : [{ path, steps, deliveredAmount: (0, exports.amountOutAlongPath)(amountIn, steps) }];
571
+ return steps === null ? [] : [{ path, steps, deliveredAmount: (0, exports.amountOutAlongPath)(amountIn, steps, venue.feeBasisPoints) }];
522
572
  });
523
573
  // No path had every pool read — a structural non-answer, not a refusal
524
574
  // (`exact`'s own doc: `null` means "nothing to say"). NOTE THIS DOES NOT
@@ -538,7 +588,7 @@ const createPulseXCarrier = (options) => {
538
588
  amountIn,
539
589
  amountOut: best.deliveredAmount,
540
590
  referenceAmountIn,
541
- referenceAmountOut: (0, exports.amountOutAlongPath)(referenceAmountIn, best.steps),
591
+ referenceAmountOut: (0, exports.amountOutAlongPath)(referenceAmountIn, best.steps, venue.feeBasisPoints),
542
592
  });
543
593
  // The path rides on the answer, so the signer signs exactly what was
544
594
  // priced (`pulseXSwapPathForHop`). Impact is left off (not zero) when the
@@ -13,7 +13,7 @@ export { COMPOSED_ROUTE_MAX_PRICE_IMPACT_PERCENT, COMPOSED_ROUTE_MAX_VALUE_GAIN_
13
13
  export type { ComposedRouteVerdict } from './composed-route-quality.js';
14
14
  export { entryChainAnchorsForPair } from './entry-chain-anchor.js';
15
15
  export type { EntryChainAnchor, EntryChainCrossingCall } from './entry-chain-anchor.js';
16
- export type { EstimateBasis, RouteData, RouteHopData, RouteKind, RouteOutputData, RouteSectionData, RouteTokenRef, } from './route-data.js';
16
+ export type { EstimateBasis, RouteData, RouteGasByChain, RouteHopData, RouteKind, RouteOutputData, RouteSectionData, RouteTokenRef, } from './route-data.js';
17
17
  export { usdValueOfAmount } from './usd-value.js';
18
18
  export { formatUsd, formatUsdNullable } from './format.js';
19
19
  export { BRIDGE_SETTLEMENT_ETA_MINUTES, PULSEX_MARGINAL_REFERENCE_DIVISOR, pulsechainChainId, addUsdValues, providerDisplayName, resolveEntryChainName, buildCandidateRouteData, buildConversionRouteData, buildDirectRouteData, buildPulseXSwapEstimateData, buildPulseXSwapSectionData, buildOutboundRouteData, buildSameChainSwapRouteData, candidateDeliveredUsd, candidateNetValueUsd, candidateOutsideFeesUsd, candidatePaidUsd, } from './producers.js';
@@ -24,14 +24,18 @@ export { composableHopBasis, composeRouteDelivery, hopOutputAmount, } from './se
24
24
  export type { ComposableHop, ComposableHopFigure, ComposeRefusalReason, ComposedRouteDelivery, ExchangeRate, } from './search/compose.js';
25
25
  export { GAS_TOPUP_PENALTY_FLOOR_USD, GAS_TOPUP_PENALTY_PPM, SIGNATURE_PENALTY_FLOOR_USD, SIGNATURE_PENALTY_PPM, compareRoutePlansByGasAdjustedDeliveredAmount, compareRoutePlansByScoreAdjustedDeliveredAmount, gasAdjustedDeliveredAmount, scoreRoutePlan, sectionIsFundedByLanding, waitPenaltyPpm, zeroGasCostFor, } from './search/score.js';
26
26
  export type { GasCostFor, GasCostQuote, RouteScoreInputs } from './search/score.js';
27
+ export { WRAP_CARRIER_ID, carrierProviderKey, carrierStepKind } from './carrier-provider-key.js';
28
+ export type { CarrierStepKind } from './carrier-provider-key.js';
27
29
  export { buildRouteCandidateFromPlan, buildRouteDataFromPlan, buildRouteScoreInputsFromPlan, deriveDeferredCrossingFromPlan, deriveEntryChainIdFromPlan, deriveOmnibridgeProviderFromPlan, deriveViaChainIdsFromPlan, derivePlanKind, } from './search/plan-route-data.js';
28
30
  export type { PlanCandidateInputs, PlanRouteDataInputs, PlanSectionPricing, PlanValuation, ResolveNodeToken, } from './search/plan-route-data.js';
29
31
  export { createOmnibridgeCarrier, withOmnibridgeEntryFusing, } from './carriers/omnibridge.js';
30
32
  export type { BridgeablePair, CreateOmnibridgeCarrierOptions, } from './carriers/omnibridge.js';
31
- export { createPulseXCarrier, pulseXRouterForEdge, pulseXSwapPathForHop, pulseXVenues, pulseXWrappedNativePath, } from './carriers/pulsex.js';
33
+ export { createPulseXCarrier, pulseXRouterForEdge, venueForEdge, pulseXSwapPathForHop, pulseXVenues, pulseXWrappedNativePath, } from './carriers/pulsex.js';
32
34
  export type { CreatePulseXCarrierOptions, PulseXVenue } from './carriers/pulsex.js';
33
35
  export { bestPulseXPathQuote, candidatePulseXPaths, pulseXHubTokens } from './carriers/pulsex-paths.js';
34
36
  export type { PulseXHubToken, PulseXPathQuote } from './carriers/pulsex-paths.js';
37
+ export { findSwapVenue, resolveSwapVenues } from '../swap-venues.js';
38
+ export type { SwapVenue, SwapVenues } from '../swap-venues.js';
35
39
  export { createWrapCarrier } from './carriers/wrap.js';
36
40
  export type { CarrierAskAnswer, CarrierExactResult } from './carriers/ask-answer.js';
37
41
  export { buildPulseXSwapTransaction, buildWrapTransaction, swapMinimumOut } from './swap-transactions.js';
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.composeRouteDelivery = exports.composableHopBasis = exports.routePlanPathKey = exports.planIsRankable = exports.planIsConfirmed = exports.planComposedBasis = exports.isRateLimitedCarrier = exports.isRankableBasis = exports.isConfirmedBasis = exports.hopEdgeKey = exports.hopComposedBasis = exports.groupHopsBySignature = exports.compareRoutePlansByDeliveredAmount = exports.combineComposedPathBasis = exports.assetNodeKey = exports.RANKABLE_ESTIMATE_BASES = exports.candidatePaidUsd = exports.candidateOutsideFeesUsd = exports.candidateNetValueUsd = exports.candidateDeliveredUsd = exports.buildSameChainSwapRouteData = exports.buildOutboundRouteData = exports.buildPulseXSwapSectionData = exports.buildPulseXSwapEstimateData = exports.buildDirectRouteData = exports.buildConversionRouteData = exports.buildCandidateRouteData = exports.resolveEntryChainName = exports.providerDisplayName = exports.addUsdValues = exports.pulsechainChainId = exports.PULSEX_MARGINAL_REFERENCE_DIVISOR = exports.BRIDGE_SETTLEMENT_ETA_MINUTES = exports.formatUsdNullable = exports.formatUsd = exports.usdValueOfAmount = exports.entryChainAnchorsForPair = exports.composedRouteMayBeOffered = exports.assessComposedRoute = exports.COMPOSED_ROUTE_MAX_VALUE_LOSS_PERCENT = exports.COMPOSED_ROUTE_MAX_VALUE_GAIN_PERCENT = exports.COMPOSED_ROUTE_MAX_PRICE_IMPACT_PERCENT = exports.routeSignatureCount = exports.buildRouteDataForCandidate = exports.buildDirectCrossingCandidate = exports.pulseXConversionSwapPath = exports.omnibridgeProviderForEntryChain = exports.valueEquivalentAmount = exports.restateInDecimals = exports.netDeliveredAmount = void 0;
4
- exports.swapMinimumOut = exports.buildWrapTransaction = exports.buildPulseXSwapTransaction = exports.createWrapCarrier = exports.pulseXHubTokens = exports.candidatePulseXPaths = exports.bestPulseXPathQuote = exports.pulseXWrappedNativePath = exports.pulseXVenues = exports.pulseXSwapPathForHop = exports.pulseXRouterForEdge = exports.createPulseXCarrier = exports.withOmnibridgeEntryFusing = exports.createOmnibridgeCarrier = exports.derivePlanKind = exports.deriveViaChainIdsFromPlan = exports.deriveOmnibridgeProviderFromPlan = exports.deriveEntryChainIdFromPlan = exports.deriveDeferredCrossingFromPlan = exports.buildRouteScoreInputsFromPlan = exports.buildRouteDataFromPlan = exports.buildRouteCandidateFromPlan = exports.zeroGasCostFor = exports.waitPenaltyPpm = exports.sectionIsFundedByLanding = exports.scoreRoutePlan = exports.gasAdjustedDeliveredAmount = exports.compareRoutePlansByScoreAdjustedDeliveredAmount = exports.compareRoutePlansByGasAdjustedDeliveredAmount = exports.SIGNATURE_PENALTY_PPM = exports.SIGNATURE_PENALTY_FLOOR_USD = exports.GAS_TOPUP_PENALTY_PPM = exports.GAS_TOPUP_PENALTY_FLOOR_USD = exports.hopOutputAmount = void 0;
4
+ exports.swapMinimumOut = exports.buildWrapTransaction = exports.buildPulseXSwapTransaction = exports.createWrapCarrier = exports.resolveSwapVenues = exports.findSwapVenue = exports.pulseXHubTokens = exports.candidatePulseXPaths = exports.bestPulseXPathQuote = exports.pulseXWrappedNativePath = exports.pulseXVenues = exports.pulseXSwapPathForHop = exports.venueForEdge = exports.pulseXRouterForEdge = exports.createPulseXCarrier = exports.withOmnibridgeEntryFusing = exports.createOmnibridgeCarrier = exports.derivePlanKind = exports.deriveViaChainIdsFromPlan = exports.deriveOmnibridgeProviderFromPlan = exports.deriveEntryChainIdFromPlan = exports.deriveDeferredCrossingFromPlan = exports.buildRouteScoreInputsFromPlan = exports.buildRouteDataFromPlan = exports.buildRouteCandidateFromPlan = exports.carrierStepKind = exports.carrierProviderKey = exports.WRAP_CARRIER_ID = exports.zeroGasCostFor = exports.waitPenaltyPpm = exports.sectionIsFundedByLanding = exports.scoreRoutePlan = exports.gasAdjustedDeliveredAmount = exports.compareRoutePlansByScoreAdjustedDeliveredAmount = exports.compareRoutePlansByGasAdjustedDeliveredAmount = exports.SIGNATURE_PENALTY_PPM = exports.SIGNATURE_PENALTY_FLOOR_USD = exports.GAS_TOPUP_PENALTY_PPM = exports.GAS_TOPUP_PENALTY_FLOOR_USD = exports.hopOutputAmount = void 0;
5
5
  /**
6
6
  * Framework-agnostic routing core for the Gibs bridge. Holds the raw numeric
7
7
  * primitives, the candidate shape, and candidate construction — none of which
@@ -92,6 +92,10 @@ Object.defineProperty(exports, "scoreRoutePlan", { enumerable: true, get: functi
92
92
  Object.defineProperty(exports, "sectionIsFundedByLanding", { enumerable: true, get: function () { return score_js_1.sectionIsFundedByLanding; } });
93
93
  Object.defineProperty(exports, "waitPenaltyPpm", { enumerable: true, get: function () { return score_js_1.waitPenaltyPpm; } });
94
94
  Object.defineProperty(exports, "zeroGasCostFor", { enumerable: true, get: function () { return score_js_1.zeroGasCostFor; } });
95
+ var carrier_provider_key_js_1 = require("./carrier-provider-key.js");
96
+ Object.defineProperty(exports, "WRAP_CARRIER_ID", { enumerable: true, get: function () { return carrier_provider_key_js_1.WRAP_CARRIER_ID; } });
97
+ Object.defineProperty(exports, "carrierProviderKey", { enumerable: true, get: function () { return carrier_provider_key_js_1.carrierProviderKey; } });
98
+ Object.defineProperty(exports, "carrierStepKind", { enumerable: true, get: function () { return carrier_provider_key_js_1.carrierStepKind; } });
95
99
  // General route search — Phase 1: plan-route-data.ts. Turns a priced
96
100
  // RoutePlan into the same RouteData/RouteCandidate/RouteScoreInputs shapes
97
101
  // today's four hand-written producers emit — see that module's head doc.
@@ -117,6 +121,7 @@ Object.defineProperty(exports, "withOmnibridgeEntryFusing", { enumerable: true,
117
121
  var pulsex_js_1 = require("./carriers/pulsex.js");
118
122
  Object.defineProperty(exports, "createPulseXCarrier", { enumerable: true, get: function () { return pulsex_js_1.createPulseXCarrier; } });
119
123
  Object.defineProperty(exports, "pulseXRouterForEdge", { enumerable: true, get: function () { return pulsex_js_1.pulseXRouterForEdge; } });
124
+ Object.defineProperty(exports, "venueForEdge", { enumerable: true, get: function () { return pulsex_js_1.venueForEdge; } });
120
125
  Object.defineProperty(exports, "pulseXSwapPathForHop", { enumerable: true, get: function () { return pulsex_js_1.pulseXSwapPathForHop; } });
121
126
  Object.defineProperty(exports, "pulseXVenues", { enumerable: true, get: function () { return pulsex_js_1.pulseXVenues; } });
122
127
  Object.defineProperty(exports, "pulseXWrappedNativePath", { enumerable: true, get: function () { return pulsex_js_1.pulseXWrappedNativePath; } });
@@ -124,6 +129,9 @@ var pulsex_paths_js_1 = require("./carriers/pulsex-paths.js");
124
129
  Object.defineProperty(exports, "bestPulseXPathQuote", { enumerable: true, get: function () { return pulsex_paths_js_1.bestPulseXPathQuote; } });
125
130
  Object.defineProperty(exports, "candidatePulseXPaths", { enumerable: true, get: function () { return pulsex_paths_js_1.candidatePulseXPaths; } });
126
131
  Object.defineProperty(exports, "pulseXHubTokens", { enumerable: true, get: function () { return pulsex_paths_js_1.pulseXHubTokens; } });
132
+ var swap_venues_js_1 = require("../swap-venues.js");
133
+ Object.defineProperty(exports, "findSwapVenue", { enumerable: true, get: function () { return swap_venues_js_1.findSwapVenue; } });
134
+ Object.defineProperty(exports, "resolveSwapVenues", { enumerable: true, get: function () { return swap_venues_js_1.resolveSwapVenues; } });
127
135
  var wrap_js_1 = require("./carriers/wrap.js");
128
136
  Object.defineProperty(exports, "createWrapCarrier", { enumerable: true, get: function () { return wrap_js_1.createWrapCarrier; } });
129
137
  // The same-chain swap and wrap builders. The interface's section signing and