@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.
- package/README.md +52 -1
- package/dist/cjs/config.d.ts +18 -3
- package/dist/cjs/config.js +49 -17
- package/dist/cjs/execution.d.ts +17 -4
- package/dist/cjs/execution.js +40 -13
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/prices.d.ts +10 -0
- package/dist/cjs/prices.js +54 -2
- package/dist/cjs/routing/carrier-provider-key.d.ts +31 -0
- package/dist/cjs/routing/carrier-provider-key.js +42 -0
- package/dist/cjs/routing/carriers/pulsex.d.ts +50 -25
- package/dist/cjs/routing/carriers/pulsex.js +135 -85
- package/dist/cjs/routing/index.d.ts +6 -2
- package/dist/cjs/routing/index.js +9 -1
- package/dist/cjs/routing/route-data.d.ts +47 -5
- package/dist/cjs/routing/search/plan-route-data.d.ts +17 -1
- package/dist/cjs/routing/search/plan-route-data.js +30 -7
- package/dist/cjs/routing/swap-transactions.d.ts +7 -3
- package/dist/cjs/routing/swap-transactions.js +6 -4
- package/dist/cjs/swap-venues.d.ts +43 -0
- package/dist/cjs/swap-venues.js +29 -0
- package/dist/config.d.ts +18 -3
- package/dist/config.js +48 -16
- package/dist/execution.d.ts +17 -4
- package/dist/execution.js +41 -14
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/prices.d.ts +10 -0
- package/dist/prices.js +52 -1
- package/dist/routing/carrier-provider-key.d.ts +31 -0
- package/dist/routing/carrier-provider-key.js +37 -0
- package/dist/routing/carriers/pulsex.d.ts +50 -25
- package/dist/routing/carriers/pulsex.js +133 -84
- package/dist/routing/index.d.ts +6 -2
- package/dist/routing/index.js +3 -1
- package/dist/routing/route-data.d.ts +47 -5
- package/dist/routing/search/plan-route-data.d.ts +17 -1
- package/dist/routing/search/plan-route-data.js +30 -7
- package/dist/routing/swap-transactions.d.ts +7 -3
- package/dist/routing/swap-transactions.js +7 -5
- package/dist/swap-venues.d.ts +43 -0
- package/dist/swap-venues.js +24 -0
- package/package.json +3 -3
package/dist/execution.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { zeroAddress } from 'viem';
|
|
2
2
|
import * as abis from './abis.js';
|
|
3
3
|
import { Providers, toChain } from './config.js';
|
|
4
|
+
import { resolveSwapVenues } from './swap-venues.js';
|
|
4
5
|
import { aggregatorOriginCalls, } from './consolidated-quote.js';
|
|
5
|
-
import {
|
|
6
|
+
import { pulseXSwapPathForHop, venueForEdge } from './routing/carriers/pulsex.js';
|
|
6
7
|
import { buildPulseXSwapTransaction, buildWrapTransaction, swapMinimumOut } from './routing/swap-transactions.js';
|
|
7
8
|
import { approvalAmounts, approveCall, bridgePathway, destinationDataParam, feeDirectorStructEncoded, feeTypeSettings, omnibridgeApproval, transactionInputs, } from './settings.js';
|
|
8
9
|
/**
|
|
@@ -94,10 +95,30 @@ const omnibridgeCalls = (leg, account) => {
|
|
|
94
95
|
delivery: deliveryTermsOf(leg.delivery),
|
|
95
96
|
};
|
|
96
97
|
};
|
|
97
|
-
|
|
98
|
+
/**
|
|
99
|
+
* The venue a swap edge was priced on, from the venues execution was given.
|
|
100
|
+
* A router that is not in those venues THROWS: signing on another router, on
|
|
101
|
+
* PulseX most of all, would trade against pools the reader was never shown.
|
|
102
|
+
*
|
|
103
|
+
* @param venues - the venues passed to execution
|
|
104
|
+
* @param edge - the swap edge
|
|
105
|
+
* @returns the venue
|
|
106
|
+
* @throws when the edge's router is not in `venues`, or its chain has no venue
|
|
107
|
+
*/
|
|
108
|
+
const requireSwapVenue = (venues, edge) => {
|
|
109
|
+
const venue = venueForEdge(venues, edge);
|
|
110
|
+
if (venue !== null)
|
|
111
|
+
return venue;
|
|
112
|
+
const router = edge.venue ?? 'the default router';
|
|
113
|
+
throw new Error(`The swap was priced on ${router} on chain ${edge.from.chainId}, but that router is not in the swap venues passed to execution. ` +
|
|
114
|
+
'Pass the same swapVenues the route search used.');
|
|
115
|
+
};
|
|
116
|
+
const pulseXSwapCalls = (leg, venues) => {
|
|
98
117
|
const { edge } = leg.hop;
|
|
99
118
|
const chainId = edge.from.chainId;
|
|
100
|
-
|
|
119
|
+
if (edge.carrier !== 'PulseX')
|
|
120
|
+
return refusal({ reason: 'swap-refused' });
|
|
121
|
+
const routerAddress = requireSwapVenue(venues, edge).router;
|
|
101
122
|
// The builder refuses a hop that records no priced path, a router other
|
|
102
123
|
// than the edge's own, and a leg on screen that disagrees.
|
|
103
124
|
const call = buildPulseXSwapTransaction({
|
|
@@ -109,8 +130,9 @@ const pulseXSwapCalls = (leg) => {
|
|
|
109
130
|
signedLeg: { kind: 'swap', chainId },
|
|
110
131
|
chainId,
|
|
111
132
|
routerAddress,
|
|
133
|
+
venues,
|
|
112
134
|
});
|
|
113
|
-
if (call === null
|
|
135
|
+
if (call === null)
|
|
114
136
|
return refusal({ reason: 'swap-refused' });
|
|
115
137
|
const spendsNative = edge.from.address.toLowerCase() === zeroAddress;
|
|
116
138
|
return {
|
|
@@ -154,11 +176,11 @@ const aggregatorCalls = (leg) => {
|
|
|
154
176
|
delivery: null,
|
|
155
177
|
};
|
|
156
178
|
};
|
|
157
|
-
const legCalls = (leg, account) => {
|
|
179
|
+
const legCalls = (leg, account, venues) => {
|
|
158
180
|
if (leg.kind === 'omnibridge')
|
|
159
181
|
return omnibridgeCalls(leg, account);
|
|
160
182
|
if (leg.kind === 'pulsex-swap')
|
|
161
|
-
return pulseXSwapCalls(leg);
|
|
183
|
+
return pulseXSwapCalls(leg, venues);
|
|
162
184
|
if (leg.kind === 'wrap')
|
|
163
185
|
return wrapCalls(leg);
|
|
164
186
|
return aggregatorCalls(leg);
|
|
@@ -183,10 +205,13 @@ const approvalTransactions = async ({ approval, account, readAllowance, }) => {
|
|
|
183
205
|
* @param options.account - the account that signs every transaction
|
|
184
206
|
* @param options.legs - the legs, in the order the wallet signs them
|
|
185
207
|
* @param options.readAllowance - reads an allowance on chain; see {@link AllowanceReader}
|
|
208
|
+
* @param options.swapVenues - the routers swaps may sign on, merged over the defaults; a swap whose router is in none of them throws
|
|
186
209
|
* @returns the ordered transactions, or the first leg that cannot be planned
|
|
210
|
+
* @throws when a swap leg's router is not in the swap venues
|
|
187
211
|
*/
|
|
188
|
-
export const planExecution = async ({ account, legs, readAllowance, }) => {
|
|
189
|
-
const
|
|
212
|
+
export const planExecution = async ({ account, legs, readAllowance, swapVenues, }) => {
|
|
213
|
+
const venues = resolveSwapVenues(swapVenues);
|
|
214
|
+
const calls = legs.map((leg) => legCalls(leg, account, venues));
|
|
190
215
|
const refusedIndex = calls.findIndex((entry) => entry.kind === 'refused');
|
|
191
216
|
const refused = calls[refusedIndex];
|
|
192
217
|
if (refused !== undefined && refused.kind === 'refused') {
|
|
@@ -363,7 +388,7 @@ const sectionWindowProblem = ({ firstSectionIndex, plannedCount, sectionCount, }
|
|
|
363
388
|
* @returns the ordered transactions with the deliveries they buy, or the first section that cannot be planned
|
|
364
389
|
*/
|
|
365
390
|
export const planCandidateExecution = async (inputs) => {
|
|
366
|
-
const { candidate, account, readAllowance, resolveToken, sections } = inputs;
|
|
391
|
+
const { candidate, account, readAllowance, resolveToken, sections, swapVenues } = inputs;
|
|
367
392
|
const firstSectionIndex = inputs.firstSectionIndex ?? 0;
|
|
368
393
|
const plan = candidate.plan;
|
|
369
394
|
const allSections = plan === undefined ? null : planSections(plan);
|
|
@@ -386,7 +411,7 @@ export const planCandidateExecution = async (inputs) => {
|
|
|
386
411
|
return { kind: 'refused', sectionIndex: firstSectionIndex + refusedIndex, refusal: refused.refusal };
|
|
387
412
|
}
|
|
388
413
|
const legs = sectionLegs.flatMap((entry) => (entry.kind === 'leg' ? [entry.leg] : []));
|
|
389
|
-
const planned = await planExecution({ account, legs, readAllowance });
|
|
414
|
+
const planned = await planExecution({ account, legs, readAllowance, ...(swapVenues === undefined ? {} : { swapVenues }) });
|
|
390
415
|
if (planned.kind === 'refused') {
|
|
391
416
|
return { kind: 'refused', sectionIndex: firstSectionIndex + planned.legIndex, refusal: planned.refusal };
|
|
392
417
|
}
|
|
@@ -406,13 +431,15 @@ export const planCandidateExecution = async (inputs) => {
|
|
|
406
431
|
* @param options.hop - the swap hop; its recorded path and edge name what to read
|
|
407
432
|
* @param options.amountIn - the amount the swap spends, in base units
|
|
408
433
|
* @param options.client - a client that can call `readContract`
|
|
409
|
-
* @
|
|
434
|
+
* @param options.swapVenues - the routers swaps may sign on, merged over the defaults
|
|
435
|
+
* @returns the amount the last token of the path delivers, or null when the hop records no path, the amount is not positive, or the read fails or returns nothing
|
|
436
|
+
* @throws when the hop records a path but its router is not in the swap venues
|
|
410
437
|
*/
|
|
411
|
-
export const readPulseXSectionQuote = async ({ hop, amountIn, client, }) => {
|
|
438
|
+
export const readPulseXSectionQuote = async ({ hop, amountIn, client, swapVenues, }) => {
|
|
412
439
|
const path = pulseXSwapPathForHop(hop);
|
|
413
|
-
|
|
414
|
-
if (path === null || router === null || amountIn <= 0n)
|
|
440
|
+
if (path === null || amountIn <= 0n)
|
|
415
441
|
return null;
|
|
442
|
+
const router = requireSwapVenue(resolveSwapVenues(swapVenues), hop.edge).router;
|
|
416
443
|
try {
|
|
417
444
|
const amounts = await client.readContract({
|
|
418
445
|
address: router,
|
package/dist/index.d.ts
CHANGED
|
@@ -17,6 +17,7 @@ export * from './referral.js';
|
|
|
17
17
|
export * from './route-steps.js';
|
|
18
18
|
export * from './routing/index.js';
|
|
19
19
|
export * from './settings.js';
|
|
20
|
+
export * from './swap-venues.js';
|
|
20
21
|
export * from './types.js';
|
|
21
22
|
export * from './claims.js';
|
|
22
23
|
export * from './execution.js';
|
package/dist/index.js
CHANGED
|
@@ -17,6 +17,7 @@ export * from './referral.js';
|
|
|
17
17
|
export * from './route-steps.js';
|
|
18
18
|
export * from './routing/index.js';
|
|
19
19
|
export * from './settings.js';
|
|
20
|
+
export * from './swap-venues.js';
|
|
20
21
|
export * from './types.js';
|
|
21
22
|
export * from './claims.js';
|
|
22
23
|
export * from './execution.js';
|
package/dist/prices.d.ts
CHANGED
|
@@ -105,3 +105,13 @@ export declare const resolveTokenPriceUsd: (token: Token, { pulsexPrices, lifiPr
|
|
|
105
105
|
pulsexPrices: Map<string, number>;
|
|
106
106
|
lifiPrices: Map<string, number>;
|
|
107
107
|
}) => number | null;
|
|
108
|
+
/**
|
|
109
|
+
* The chain's canonical wrapped native address when `token` is the native
|
|
110
|
+
* coin (zero address) or that wrapper itself, and null for every other token.
|
|
111
|
+
* Only the SAME chain's pair is returned: a bridged copy of a wrapper on
|
|
112
|
+
* another chain is a different token and keeps its own price.
|
|
113
|
+
*
|
|
114
|
+
* @param token - the token to test
|
|
115
|
+
* @returns the wrapped native address on the token's own chain, or null
|
|
116
|
+
*/
|
|
117
|
+
export declare const sameChainWrappedNative: (token: Token) => Hex | null;
|
package/dist/prices.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { formatUnits } from 'viem';
|
|
2
|
-
import { Chains, nativeAssetOut } from './config.js';
|
|
2
|
+
import { Chains, nativeAssetOut, toChain } from './config.js';
|
|
3
3
|
/**
|
|
4
4
|
* PulseChain mainnet numeric chain id (`Chains.PLS` = `0x171`). Tokens on this
|
|
5
5
|
* chain (and its testnet sibling below) are priced on-chain via PulseX rather
|
|
@@ -138,6 +138,57 @@ export const computeUsdPriceFromAmountsOut = ({ results, stableDecimals = PULSEC
|
|
|
138
138
|
* @returns the USD price as a number, or null when no source can price it
|
|
139
139
|
*/
|
|
140
140
|
export const resolveTokenPriceUsd = (token, { pulsexPrices, lifiPrices, }) => {
|
|
141
|
+
const wrappedNative = sameChainWrappedNative(token);
|
|
142
|
+
if (wrappedNative !== null) {
|
|
143
|
+
return resolveNativeFamilyPriceUsd(token, wrappedNative, { pulsexPrices, lifiPrices });
|
|
144
|
+
}
|
|
145
|
+
return resolveOwnPriceUsd(token, { pulsexPrices, lifiPrices });
|
|
146
|
+
};
|
|
147
|
+
/**
|
|
148
|
+
* The chain's canonical wrapped native address when `token` is the native
|
|
149
|
+
* coin (zero address) or that wrapper itself, and null for every other token.
|
|
150
|
+
* Only the SAME chain's pair is returned: a bridged copy of a wrapper on
|
|
151
|
+
* another chain is a different token and keeps its own price.
|
|
152
|
+
*
|
|
153
|
+
* @param token - the token to test
|
|
154
|
+
* @returns the wrapped native address on the token's own chain, or null
|
|
155
|
+
*/
|
|
156
|
+
export const sameChainWrappedNative = (token) => {
|
|
157
|
+
const wrapped = nativeAssetOut[toChain(token.chainId)];
|
|
158
|
+
if (wrapped === undefined) {
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
const isNativeCoin = sameAddress(token.address, NATIVE_TOKEN_ADDRESS);
|
|
162
|
+
return isNativeCoin || sameAddress(token.address, wrapped) ? wrapped : null;
|
|
163
|
+
};
|
|
164
|
+
/**
|
|
165
|
+
* One price for a native coin and its canonical wrapper. The contract wraps
|
|
166
|
+
* and unwraps 1:1, so two prices would show a value loss on a wrap step that
|
|
167
|
+
* loses nothing.
|
|
168
|
+
*
|
|
169
|
+
* Off PulseChain the native coin's market feed (LI.FI) wins. The wrapper's
|
|
170
|
+
* own price there is the PulseX price of its bridged copy (it carries a
|
|
171
|
+
* PulseChain origin link), which is a derivative market with its own
|
|
172
|
+
* premium or discount. The coin's feed prices the underlying asset. When the
|
|
173
|
+
* feed has no native price, the wrapper's feed price, then its own resolved
|
|
174
|
+
* price, stand in.
|
|
175
|
+
*
|
|
176
|
+
* On PulseChain both are priced by PulseX through the WPLS path, so the
|
|
177
|
+
* wrapper's entry is used and the coin's entry stands in when the wrapper was
|
|
178
|
+
* not in the priced set.
|
|
179
|
+
*/
|
|
180
|
+
const resolveNativeFamilyPriceUsd = (token, wrappedNative, maps) => {
|
|
181
|
+
const wrapped = { ...token, address: wrappedNative };
|
|
182
|
+
if (isPulsechain(token.chainId)) {
|
|
183
|
+
return (resolveOwnPriceUsd(wrapped, maps) ??
|
|
184
|
+
resolveOwnPriceUsd({ ...token, address: NATIVE_TOKEN_ADDRESS }, maps));
|
|
185
|
+
}
|
|
186
|
+
return (maps.lifiPrices.get(lifiPriceKey(token.chainId, NATIVE_TOKEN_ADDRESS)) ??
|
|
187
|
+
maps.lifiPrices.get(lifiPriceKey(token.chainId, wrappedNative)) ??
|
|
188
|
+
resolveOwnPriceUsd(wrapped, maps));
|
|
189
|
+
};
|
|
190
|
+
/** The token's price by its own address, with no native-wrapper pairing. */
|
|
191
|
+
const resolveOwnPriceUsd = (token, { pulsexPrices, lifiPrices, }) => {
|
|
141
192
|
if (isPulsechain(token.chainId)) {
|
|
142
193
|
if (sameAddress(token.address, PULSECHAIN_USD_ANCHOR_ADDRESS)) {
|
|
143
194
|
return 1;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type ProviderKey } from '../providers.js';
|
|
2
|
+
/**
|
|
3
|
+
* The carrier id of the native-coin wrap and unwrap step
|
|
4
|
+
* (`routing/carriers/wrap.ts`).
|
|
5
|
+
*/
|
|
6
|
+
export declare const WRAP_CARRIER_ID = "wrap";
|
|
7
|
+
/**
|
|
8
|
+
* The steps a route can take that no third-party provider performs. A step of
|
|
9
|
+
* this kind is drawn from its own mark, never from a provider's.
|
|
10
|
+
*/
|
|
11
|
+
export type CarrierStepKind = 'wrap';
|
|
12
|
+
/**
|
|
13
|
+
* The one place an engine carrier id becomes a {@link ProviderKey}.
|
|
14
|
+
*
|
|
15
|
+
* AN ENGINE CARRIER ID IS NOT A PROVIDER KEY. The engine is a plug-in host: a
|
|
16
|
+
* carrier id is any string, and one of them, `'wrap'`, names a step that no
|
|
17
|
+
* provider performs. Handing a raw id to the logo, glyph, or name tables drew a
|
|
18
|
+
* blank mark and logged an error. Route data resolves the key here, once, and
|
|
19
|
+
* every display site reads the resolved key.
|
|
20
|
+
*
|
|
21
|
+
* @param carrierId - the `carrier` of a planned hop's edge
|
|
22
|
+
* @returns the provider key, or null when no registered provider carries that id
|
|
23
|
+
*/
|
|
24
|
+
export declare const carrierProviderKey: (carrierId: string) => ProviderKey | null;
|
|
25
|
+
/**
|
|
26
|
+
* The kind of provider-less step a carrier id performs.
|
|
27
|
+
*
|
|
28
|
+
* @param carrierId - the `carrier` of a planned hop's edge
|
|
29
|
+
* @returns the step kind, or null when the carrier is a provider or unknown
|
|
30
|
+
*/
|
|
31
|
+
export declare const carrierStepKind: (carrierId: string) => CarrierStepKind | null;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Providers } from '../config.js';
|
|
2
|
+
import { providerRegistry } from '../providers.js';
|
|
3
|
+
/**
|
|
4
|
+
* The carrier id of the native-coin wrap and unwrap step
|
|
5
|
+
* (`routing/carriers/wrap.ts`).
|
|
6
|
+
*/
|
|
7
|
+
export const WRAP_CARRIER_ID = 'wrap';
|
|
8
|
+
/**
|
|
9
|
+
* Every engine carrier id that IS a provider, mapped to its {@link ProviderKey}.
|
|
10
|
+
* The omnibridge crossings carry the provider value itself; the aggregators
|
|
11
|
+
* carry their registry id; the PulseChain exchange carries its own literal.
|
|
12
|
+
*/
|
|
13
|
+
const providerKeyByCarrierId = new Map([
|
|
14
|
+
...Object.values(Providers).map((provider) => [provider, provider]),
|
|
15
|
+
...providerRegistry.map((descriptor) => [descriptor.id, descriptor.id]),
|
|
16
|
+
['PulseX', 'PulseX'],
|
|
17
|
+
]);
|
|
18
|
+
/**
|
|
19
|
+
* The one place an engine carrier id becomes a {@link ProviderKey}.
|
|
20
|
+
*
|
|
21
|
+
* AN ENGINE CARRIER ID IS NOT A PROVIDER KEY. The engine is a plug-in host: a
|
|
22
|
+
* carrier id is any string, and one of them, `'wrap'`, names a step that no
|
|
23
|
+
* provider performs. Handing a raw id to the logo, glyph, or name tables drew a
|
|
24
|
+
* blank mark and logged an error. Route data resolves the key here, once, and
|
|
25
|
+
* every display site reads the resolved key.
|
|
26
|
+
*
|
|
27
|
+
* @param carrierId - the `carrier` of a planned hop's edge
|
|
28
|
+
* @returns the provider key, or null when no registered provider carries that id
|
|
29
|
+
*/
|
|
30
|
+
export const carrierProviderKey = (carrierId) => providerKeyByCarrierId.get(carrierId) ?? null;
|
|
31
|
+
/**
|
|
32
|
+
* The kind of provider-less step a carrier id performs.
|
|
33
|
+
*
|
|
34
|
+
* @param carrierId - the `carrier` of a planned hop's edge
|
|
35
|
+
* @returns the step kind, or null when the carrier is a provider or unknown
|
|
36
|
+
*/
|
|
37
|
+
export const carrierStepKind = (carrierId) => carrierId === WRAP_CARRIER_ID ? 'wrap' : null;
|
|
@@ -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
|
|
7
|
-
*
|
|
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:
|
|
17
|
-
*
|
|
18
|
-
*
|
|
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
|
|
25
|
-
* against. Reads the edge's own {@link HopEdge.venue}; an edge with none
|
|
26
|
-
*
|
|
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
|
|
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">
|
|
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
|
|
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
|
|
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 -
|
|
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
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
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
|
|
161
|
+
* Defaults to every offered venue.
|
|
137
162
|
*/
|
|
138
163
|
readonly routers?: readonly Hex[];
|
|
139
164
|
};
|