@gibs/bridge-sdk 1.12.0 → 1.13.1
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/LICENSE +15 -0
- package/README.md +234 -432
- package/dist/abis.d.ts +1 -0
- package/dist/bridge-limits.d.ts +103 -0
- package/dist/bridge-limits.js +84 -0
- package/dist/chain-info.d.ts +169 -0
- package/dist/chain-info.js +410 -0
- package/dist/chain-names.d.ts +160 -0
- package/dist/chain-names.js +200 -0
- package/dist/chains.d.ts +65 -0
- package/dist/chains.js +284 -0
- package/dist/config.d.ts +216 -0
- package/dist/config.js +493 -0
- package/dist/consolidated-quote.d.ts +554 -0
- package/dist/consolidated-quote.js +773 -0
- package/dist/destination-calldata.d.ts +118 -0
- package/dist/destination-calldata.js +152 -0
- package/dist/ecosystems.d.ts +217 -0
- package/dist/ecosystems.js +288 -0
- package/dist/fee-type.d.ts +10 -0
- package/dist/fee-type.js +9 -0
- package/dist/hyperliquid-execution.d.ts +152 -0
- package/dist/hyperliquid-execution.js +168 -0
- package/dist/image-links.d.ts +117 -0
- package/dist/image-links.js +142 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +20 -0
- package/dist/lifi-execution-guard.d.ts +199 -0
- package/dist/lifi-execution-guard.js +400 -0
- package/dist/near-intents-conformance.d.ts +85 -0
- package/dist/near-intents-conformance.js +329 -0
- package/dist/near-intents-route.d.ts +47 -0
- package/dist/near-intents-route.js +265 -0
- package/dist/near-intents.d.ts +524 -0
- package/dist/near-intents.js +1055 -0
- package/dist/origin-deposit.d.ts +326 -0
- package/dist/origin-deposit.js +68 -0
- package/dist/pre-quote.d.ts +198 -0
- package/dist/pre-quote.js +175 -0
- package/dist/prices.d.ts +107 -0
- package/dist/prices.js +162 -0
- package/dist/providers.d.ts +221 -0
- package/dist/providers.js +157 -0
- package/dist/quote-fees.d.ts +102 -0
- package/dist/quote-fees.js +195 -0
- package/dist/referral.d.ts +77 -0
- package/dist/referral.js +72 -0
- package/dist/relay-currencies.d.ts +47 -0
- package/dist/relay-currencies.js +89 -0
- package/dist/relay-quote.d.ts +301 -0
- package/dist/relay-quote.js +983 -0
- package/dist/route-steps.d.ts +138 -0
- package/dist/route-steps.js +305 -0
- package/dist/routing/amounts.d.ts +80 -0
- package/dist/routing/amounts.js +120 -0
- package/dist/routing/candidate-route.d.ts +43 -0
- package/dist/routing/candidate-route.js +45 -0
- package/dist/routing/candidate.d.ts +237 -0
- package/dist/routing/candidate.js +96 -0
- package/dist/routing/carriers/ask-answer.d.ts +60 -0
- package/dist/routing/carriers/ask-answer.js +1 -0
- package/dist/routing/carriers/omnibridge.d.ts +137 -0
- package/dist/routing/carriers/omnibridge.js +419 -0
- package/dist/routing/carriers/pulsex.d.ts +149 -0
- package/dist/routing/carriers/pulsex.js +453 -0
- package/dist/routing/carriers/wrap.d.ts +25 -0
- package/dist/routing/carriers/wrap.js +115 -0
- package/dist/routing/composed-route-quality.d.ts +103 -0
- package/dist/routing/composed-route-quality.js +108 -0
- package/dist/routing/entry-chain-anchor.d.ts +88 -0
- package/dist/routing/entry-chain-anchor.js +55 -0
- package/dist/routing/format.d.ts +31 -0
- package/dist/routing/format.js +58 -0
- package/dist/routing/index.d.ts +34 -0
- package/dist/routing/index.js +42 -0
- package/dist/routing/producers.d.ts +770 -0
- package/dist/routing/producers.js +1564 -0
- package/dist/routing/providers.d.ts +26 -0
- package/dist/routing/providers.js +38 -0
- package/dist/routing/route-data.d.ts +355 -0
- package/dist/routing/route-data.js +1 -0
- package/dist/routing/search/compose.d.ts +168 -0
- package/dist/routing/search/compose.js +98 -0
- package/dist/routing/search/graph.d.ts +653 -0
- package/dist/routing/search/graph.js +445 -0
- package/dist/routing/search/plan-route-data.d.ts +244 -0
- package/dist/routing/search/plan-route-data.js +767 -0
- package/dist/routing/search/score.d.ts +353 -0
- package/dist/routing/search/score.js +427 -0
- package/dist/routing/usd-value.d.ts +17 -0
- package/dist/routing/usd-value.js +25 -0
- package/dist/settings.d.ts +692 -0
- package/dist/settings.js +909 -0
- package/dist/ton-execution.d.ts +117 -0
- package/dist/ton-execution.js +247 -0
- package/dist/tron-execution.d.ts +146 -0
- package/dist/tron-execution.js +239 -0
- package/dist/types.d.ts +51 -0
- package/dist/types.js +1 -0
- package/llms.txt +169 -0
- package/package.json +204 -23
- package/src/chain-info.test.ts +0 -968
- package/src/chain-info.ts +0 -498
- package/src/chains.test.ts +0 -123
- package/src/chains.ts +0 -88
- package/src/config.test.ts +0 -679
- package/src/config.ts +0 -500
- package/src/fee-type.test.ts +0 -45
- package/src/fee-type.ts +0 -14
- package/src/image-links.test.ts +0 -160
- package/src/image-links.ts +0 -65
- package/src/index.ts +0 -8
- package/src/settings.test.ts +0 -2754
- package/src/settings.ts +0 -875
- package/src/types.ts +0 -48
- package/tsconfig.json +0 -17
- package/vitest.config.ts +0 -13
- /package/{src/abis.ts → dist/abis.js} +0 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { RouteCandidate } from './candidate.js';
|
|
2
|
+
import type { RouteData } from './route-data.js';
|
|
3
|
+
/**
|
|
4
|
+
* One door in front of the two base route builders.
|
|
5
|
+
*
|
|
6
|
+
* WHY THIS EXISTS. A candidate is drawn by one of two builders and the choice
|
|
7
|
+
* is not the caller's to make by hand. {@link buildCandidateRouteData} draws a
|
|
8
|
+
* candidate as ONE signature, because the aggregator's executor performs the
|
|
9
|
+
* omnibridge entry call on arrival. {@link buildNearIntentsTwoStepRouteData}
|
|
10
|
+
* draws it as TWO, because the aggregator that carried it cannot execute
|
|
11
|
+
* anything on the chain it delivers to, so the reader signs the crossing
|
|
12
|
+
* themselves.
|
|
13
|
+
*
|
|
14
|
+
* Every composer that builds on top of a candidate — the PulseX conversion
|
|
15
|
+
* route is the first — has to pick between them, and picking wrong is not a
|
|
16
|
+
* cosmetic error. A two-signature candidate run through the one-signature
|
|
17
|
+
* builder produces a route that claims the crossing happens inside the
|
|
18
|
+
* transaction the reader already signed. It does not. The reader would select
|
|
19
|
+
* that route, sign once, and be left holding the anchor token on the entry
|
|
20
|
+
* chain with the interface reporting the journey finished.
|
|
21
|
+
*
|
|
22
|
+
* `candidate.deferredCrossing` is the fact that decides it, and it is the same
|
|
23
|
+
* field {@link buildNearIntentsTwoStepRouteData} refuses to build without. So
|
|
24
|
+
* the two agree by construction rather than by two callers remembering the
|
|
25
|
+
* same rule.
|
|
26
|
+
*
|
|
27
|
+
* @param candidate - the priced route candidate
|
|
28
|
+
* @returns the raw route data, or null when the candidate names a deferred
|
|
29
|
+
* crossing but no omnibridge provider to perform it
|
|
30
|
+
*/
|
|
31
|
+
export declare const buildRouteDataForCandidate: (candidate: RouteCandidate) => RouteData | null;
|
|
32
|
+
/**
|
|
33
|
+
* How many wallet signatures a raw route asks the reader for.
|
|
34
|
+
*
|
|
35
|
+
* Counts the sections, because one section is one signature — that is what a
|
|
36
|
+
* section means. Named rather than left as `sections.length` at each call
|
|
37
|
+
* site, so a surface that warns about a long journey and a surface that ranks
|
|
38
|
+
* routes cannot come to different counts.
|
|
39
|
+
*
|
|
40
|
+
* @param route - the raw route data
|
|
41
|
+
* @returns the number of signatures, one per section
|
|
42
|
+
*/
|
|
43
|
+
export declare const routeSignatureCount: (route: RouteData) => number;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { buildNearIntentsTwoStepRouteData } from '../near-intents-route.js';
|
|
2
|
+
import { buildCandidateRouteData } from './producers.js';
|
|
3
|
+
/**
|
|
4
|
+
* One door in front of the two base route builders.
|
|
5
|
+
*
|
|
6
|
+
* WHY THIS EXISTS. A candidate is drawn by one of two builders and the choice
|
|
7
|
+
* is not the caller's to make by hand. {@link buildCandidateRouteData} draws a
|
|
8
|
+
* candidate as ONE signature, because the aggregator's executor performs the
|
|
9
|
+
* omnibridge entry call on arrival. {@link buildNearIntentsTwoStepRouteData}
|
|
10
|
+
* draws it as TWO, because the aggregator that carried it cannot execute
|
|
11
|
+
* anything on the chain it delivers to, so the reader signs the crossing
|
|
12
|
+
* themselves.
|
|
13
|
+
*
|
|
14
|
+
* Every composer that builds on top of a candidate — the PulseX conversion
|
|
15
|
+
* route is the first — has to pick between them, and picking wrong is not a
|
|
16
|
+
* cosmetic error. A two-signature candidate run through the one-signature
|
|
17
|
+
* builder produces a route that claims the crossing happens inside the
|
|
18
|
+
* transaction the reader already signed. It does not. The reader would select
|
|
19
|
+
* that route, sign once, and be left holding the anchor token on the entry
|
|
20
|
+
* chain with the interface reporting the journey finished.
|
|
21
|
+
*
|
|
22
|
+
* `candidate.deferredCrossing` is the fact that decides it, and it is the same
|
|
23
|
+
* field {@link buildNearIntentsTwoStepRouteData} refuses to build without. So
|
|
24
|
+
* the two agree by construction rather than by two callers remembering the
|
|
25
|
+
* same rule.
|
|
26
|
+
*
|
|
27
|
+
* @param candidate - the priced route candidate
|
|
28
|
+
* @returns the raw route data, or null when the candidate names a deferred
|
|
29
|
+
* crossing but no omnibridge provider to perform it
|
|
30
|
+
*/
|
|
31
|
+
export const buildRouteDataForCandidate = (candidate) => candidate.deferredCrossing
|
|
32
|
+
? buildNearIntentsTwoStepRouteData(candidate)
|
|
33
|
+
: buildCandidateRouteData(candidate);
|
|
34
|
+
/**
|
|
35
|
+
* How many wallet signatures a raw route asks the reader for.
|
|
36
|
+
*
|
|
37
|
+
* Counts the sections, because one section is one signature — that is what a
|
|
38
|
+
* section means. Named rather than left as `sections.length` at each call
|
|
39
|
+
* site, so a surface that warns about a long journey and a surface that ranks
|
|
40
|
+
* routes cannot come to different counts.
|
|
41
|
+
*
|
|
42
|
+
* @param route - the raw route data
|
|
43
|
+
* @returns the number of signatures, one per section
|
|
44
|
+
*/
|
|
45
|
+
export const routeSignatureCount = (route) => route.sections.length;
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import type { ConsolidatedQuote, ConsolidatedQuoteRequest } from '../consolidated-quote.js';
|
|
2
|
+
import type { Provider } from '../config.js';
|
|
3
|
+
import type { Token } from '../types.js';
|
|
4
|
+
import type { RoutePlan } from './search/graph.js';
|
|
5
|
+
/**
|
|
6
|
+
* One priced route candidate: the consolidated (aggregator) quote for the leg
|
|
7
|
+
* from the source chain to an omnibridge entry point, paired with the context
|
|
8
|
+
* needed to describe the omnibridge leg that carries it the rest of the way to
|
|
9
|
+
* PulseChain. The hook builds one of these per entry point it can quote.
|
|
10
|
+
*/
|
|
11
|
+
export type RouteCandidate = {
|
|
12
|
+
/** Stable identity for keys and selection, unique within one strip render. */
|
|
13
|
+
id: string;
|
|
14
|
+
/** The aggregator quote for the source → entry-point leg. */
|
|
15
|
+
quote: ConsolidatedQuote;
|
|
16
|
+
/**
|
|
17
|
+
* The bridge provider that crosses from the entry point to PulseChain.
|
|
18
|
+
*
|
|
19
|
+
* NULL ON A ROUTE THAT CROSSES NO BRIDGE. A candidate whose destination the
|
|
20
|
+
* omnibridge does not reach is carried entirely by the aggregator: there is
|
|
21
|
+
* no second leg, so there is no bridge to name. Null rather than a stand-in
|
|
22
|
+
* string, because every reader of this field is asking which bridge performs
|
|
23
|
+
* that leg, and naming one that is not involved is worse than saying nothing.
|
|
24
|
+
*
|
|
25
|
+
* Typed `Provider | null`, not `string | null` — the source is
|
|
26
|
+
* `omnibridgeProviderForEntryChain`, which already returns `Provider | null`.
|
|
27
|
+
*/
|
|
28
|
+
omnibridgeProvider: Provider | null;
|
|
29
|
+
/** The chain the omnibridge leg starts on (the entry point: Ethereum or BSC). */
|
|
30
|
+
entryChainId: number;
|
|
31
|
+
/**
|
|
32
|
+
* The source token the user pays with. Its symbol and resolvable image render
|
|
33
|
+
* the SOURCE node of the route's collapsed token flow — without it the source
|
|
34
|
+
* node would have no symbol (the normalized quote step carries only a raw token
|
|
35
|
+
* address) and no logo.
|
|
36
|
+
*/
|
|
37
|
+
originToken: Token;
|
|
38
|
+
/** The token the user receives on PulseChain (the route's delivered token). */
|
|
39
|
+
destinationToken: Token;
|
|
40
|
+
/**
|
|
41
|
+
* The amount delivered on PulseChain after the omnibridge crossing fee, in base
|
|
42
|
+
* units. The aggregator delivers the request's `toAmount` onto the entry chain;
|
|
43
|
+
* the omnibridge takes its crossing fee before it lands, so this is the NET the
|
|
44
|
+
* user receives — and the directly comparable "amount delivered" the routes
|
|
45
|
+
* rank on (cheapest total wins).
|
|
46
|
+
*/
|
|
47
|
+
deliveredAmount: bigint;
|
|
48
|
+
/**
|
|
49
|
+
* The omnibridge crossing fee in delivered-token base units — the amount the
|
|
50
|
+
* omnibridge takes between the entry chain and PulseChain (`toAmount` minus
|
|
51
|
+
* {@link deliveredAmount}). Carried so the route's detail view can show the
|
|
52
|
+
* BSC→PulseChain / Ethereum→PulseChain crossing fee as its OWN line, computed
|
|
53
|
+
* from the known on-chain fee rate rather than inferred from a price spread.
|
|
54
|
+
* Zero when the fee rate has not loaded.
|
|
55
|
+
*/
|
|
56
|
+
omnibridgeFeeAmount: bigint;
|
|
57
|
+
/** Per-PulseChain-token United States dollar price, or null when unpriced. */
|
|
58
|
+
destinationUsdPrice: number | null;
|
|
59
|
+
/**
|
|
60
|
+
* The amount the user actually TYPED, in origin token base units — as distinct
|
|
61
|
+
* from `quote.fromAmount`, which is what the quote turned out to need.
|
|
62
|
+
*
|
|
63
|
+
* The two differ because the quote is solved BACKWARD to a delivery target, and
|
|
64
|
+
* that target is the provider's guaranteed floor rather than its expectation.
|
|
65
|
+
* Backward-solving to the floor consumes less than was typed, and the remainder
|
|
66
|
+
* stays in the user's wallet. Carried here so the route can NAME that remainder
|
|
67
|
+
* instead of letting it show up as an unexplained gap between the amount the
|
|
68
|
+
* form prices and the value the route reports delivering.
|
|
69
|
+
*
|
|
70
|
+
* Null or absent when the caller does not know it; the route then says nothing
|
|
71
|
+
* about unspent tokens rather than guessing at a figure.
|
|
72
|
+
*/
|
|
73
|
+
requestedAmount?: bigint | null;
|
|
74
|
+
/**
|
|
75
|
+
* The crossing the reader has to come back and sign for themselves.
|
|
76
|
+
*
|
|
77
|
+
* ABSENT ON EVERY ROUTE THAT TAKES ONE SIGNATURE, which is nearly all of
|
|
78
|
+
* them. An aggregator that can execute a call on the chain it delivers to is
|
|
79
|
+
* handed the omnibridge entry call, performs it on arrival, and the whole
|
|
80
|
+
* journey is one signature — so there is no second crossing to describe.
|
|
81
|
+
*
|
|
82
|
+
* Present when the aggregator CANNOT execute on arrival. It then delivers the
|
|
83
|
+
* anchor token into the reader's own wallet on the entry chain and stops, and
|
|
84
|
+
* the omnibridge crossing becomes a second signature the reader makes later.
|
|
85
|
+
* The route must say so on its face rather than in a tooltip, which is what
|
|
86
|
+
* this field drives: see `buildNearIntentsTwoStepRouteData`.
|
|
87
|
+
*
|
|
88
|
+
* It carries the ANCHOR — what lands on the entry chain — because nothing
|
|
89
|
+
* else on this candidate does. `destinationToken` is the far side of the
|
|
90
|
+
* crossing and `originToken` the near side of the swap; the token in the
|
|
91
|
+
* middle, which is the thing the reader is left holding between the two
|
|
92
|
+
* signatures, appears nowhere else.
|
|
93
|
+
*/
|
|
94
|
+
deferredCrossing?: DeferredCrossing | null;
|
|
95
|
+
/**
|
|
96
|
+
* The consolidated quote REQUEST this candidate's `quote` actually answers,
|
|
97
|
+
* when that differs from the entry's shared one-signature `request`.
|
|
98
|
+
*
|
|
99
|
+
* ABSENT ON EVERY ONE-SIGNATURE CANDIDATE. Every candidate quoted through the
|
|
100
|
+
* competed field (`quotedCandidates` in `useRouteOptions.ts`) answers that
|
|
101
|
+
* entry's own `request` — the omnibridge entry call aimed at PulseChain — so
|
|
102
|
+
* the caller already has the right request and this field would only repeat
|
|
103
|
+
* it.
|
|
104
|
+
*
|
|
105
|
+
* PRESENT ON A TWO-STEP CANDIDATE (one with {@link deferredCrossing} set).
|
|
106
|
+
* That candidate's `quote` answers a DIFFERENT question — `twoStepRequest`
|
|
107
|
+
* in `useRouteOptions.ts`, which targets the ENTRY chain and the reader's
|
|
108
|
+
* own wallet, not PulseChain. A caller that re-quotes or records against the
|
|
109
|
+
* entry's shared `request` instead would ask a live provider to reprice a
|
|
110
|
+
* PulseChain delivery this candidate never offered, and would write a resume
|
|
111
|
+
* record naming the wrong destination token and chain. Every caller that
|
|
112
|
+
* commits or records a SELECTED candidate must read `quoteRequest` first and
|
|
113
|
+
* fall back to the entry's `request` only when this is absent.
|
|
114
|
+
*/
|
|
115
|
+
quoteRequest?: ConsolidatedQuoteRequest;
|
|
116
|
+
/**
|
|
117
|
+
* The general-search plan this candidate was built from, when it came from
|
|
118
|
+
* one — see the route-search design, section 1.
|
|
119
|
+
*
|
|
120
|
+
* ABSENT ON EVERY CANDIDATE PHASE 0 PRODUCES. Nothing builds a
|
|
121
|
+
* {@link RoutePlan} yet; the field exists so the shape it will fill is
|
|
122
|
+
* fixed before Phase 1's `enumerate.ts` starts producing plans. This is
|
|
123
|
+
* ALSO WHY IT IS OPTIONAL RATHER THAN REQUIRED: today's producers
|
|
124
|
+
* (`useAggregatorRouteCandidate`, `buildDirectCrossingCandidate`,
|
|
125
|
+
* `buildNearIntentsTwoStepRouteData`'s caller, and every stored `History`
|
|
126
|
+
* record replayed through `storedShapes`) build a `RouteCandidate` with no
|
|
127
|
+
* plan at all, and a required field would break every one of them on this
|
|
128
|
+
* phase landing alone.
|
|
129
|
+
*
|
|
130
|
+
* ONCE A CANDIDATE CARRIES A PLAN, three fields above stop being
|
|
131
|
+
* independently set and are instead DERIVED from it, so there is exactly
|
|
132
|
+
* one source of truth for what the candidate's route actually does:
|
|
133
|
+
* - {@link deferredCrossing} — present when `plan.signatures` has more than
|
|
134
|
+
* one group, taken from the first hop of the second group (the anchor
|
|
135
|
+
* the reader is left holding between signatures).
|
|
136
|
+
* - {@link entryChainId} — the `to` node's `chainId` of the plan's last
|
|
137
|
+
* hop whose carrier is `'pulsechain'` or `'tokensex'` (its bridge hop).
|
|
138
|
+
* - {@link omnibridgeProvider} — that same hop's `carrier`, or null when
|
|
139
|
+
* the plan crosses no bridge hop at all (a route the omnibridge does not
|
|
140
|
+
* reach, carried entirely by aggregators).
|
|
141
|
+
*
|
|
142
|
+
* A candidate built WITHOUT a plan keeps setting these three fields by
|
|
143
|
+
* hand, exactly as it does today; nothing about their existing meaning
|
|
144
|
+
* changes until a caller actually starts constructing plans.
|
|
145
|
+
*/
|
|
146
|
+
plan?: RoutePlan;
|
|
147
|
+
};
|
|
148
|
+
/**
|
|
149
|
+
* The anchor a two-signature route leaves the reader holding between its legs.
|
|
150
|
+
*
|
|
151
|
+
* Named for the crossing that is deferred, not for the leg that is signed now,
|
|
152
|
+
* because the deferral is the fact a reader needs and the anchor is only how it
|
|
153
|
+
* is described.
|
|
154
|
+
*/
|
|
155
|
+
export type DeferredCrossing = {
|
|
156
|
+
/** The token that lands on the entry chain, in the reader's own wallet. */
|
|
157
|
+
anchorToken: Token;
|
|
158
|
+
/** How much of it lands, in that token's base units. */
|
|
159
|
+
anchorAmount: bigint;
|
|
160
|
+
/**
|
|
161
|
+
* What the aggregator says that landing is worth, in United States dollars.
|
|
162
|
+
*
|
|
163
|
+
* The aggregator's OWN figure for the delivered side, paired with its own
|
|
164
|
+
* figure for the paid side. Two price feeds disagree by more than a small
|
|
165
|
+
* route's whole fee, so a section's cost is only a cost when both ends come
|
|
166
|
+
* from one answer.
|
|
167
|
+
*/
|
|
168
|
+
anchorUsdValue: string | null;
|
|
169
|
+
};
|
|
170
|
+
/**
|
|
171
|
+
* The inputs for {@link buildDirectCrossingCandidate}: the entry chain that equals
|
|
172
|
+
* the origin chain, the origin token paid on that chain, the anchor token delivered
|
|
173
|
+
* on PulseChain, the raw amount in, the origin token's United States dollar price,
|
|
174
|
+
* and the omnibridge crossing fee rate.
|
|
175
|
+
*/
|
|
176
|
+
export type DirectCrossingCandidateInputs = {
|
|
177
|
+
/** The omnibridge entry chain — MUST equal the origin chain for same-chain crossing. */
|
|
178
|
+
entryChainId: number;
|
|
179
|
+
/** The source chain the user's funds start on (equals entryChainId for this path). */
|
|
180
|
+
originChainId: number;
|
|
181
|
+
/** The source token the user pays with on the origin/entry chain. */
|
|
182
|
+
originToken: Token;
|
|
183
|
+
/**
|
|
184
|
+
* The anchor token delivered on PulseChain — the
|
|
185
|
+
* `effectiveEthereumDestination.pulsechainToken` or its Binance Smart Chain
|
|
186
|
+
* counterpart.
|
|
187
|
+
*/
|
|
188
|
+
destinationToken: Token;
|
|
189
|
+
/** The raw amount the user is sending, in origin token base units. */
|
|
190
|
+
amountIn: bigint;
|
|
191
|
+
/** Per-origin-token United States dollar price, or null when unpriced. */
|
|
192
|
+
originUsdPrice: number | null;
|
|
193
|
+
/**
|
|
194
|
+
* Per-destination-token United States dollar price on PulseChain, or null when
|
|
195
|
+
* unpriced. Used to value the crossing fee and the delivered amount for ranking.
|
|
196
|
+
*/
|
|
197
|
+
destinationUsdPrice: number | null;
|
|
198
|
+
/**
|
|
199
|
+
* The omnibridge foreign→home crossing fee rate (per 1e18) for this entry
|
|
200
|
+
* chain, or null when the fee config has not loaded.
|
|
201
|
+
*/
|
|
202
|
+
omnibridgeFeePerEther: bigint | null;
|
|
203
|
+
};
|
|
204
|
+
/**
|
|
205
|
+
* Synthesizes a {@link RouteCandidate} for the SAME-CHAIN direct-omnibridge
|
|
206
|
+
* conversion case: when the origin chain IS one of the omnibridge entry chains
|
|
207
|
+
* (Ethereum chain 1 or Binance Smart Chain chain 56), there is no aggregator leg
|
|
208
|
+
* to quote — the user bridges directly from that chain to PulseChain. The
|
|
209
|
+
* same-chain skip in {@link useAggregatorRouteCandidate} is correct (nothing to
|
|
210
|
+
* quote), but it left the conversion path empty. This helper fills that gap by
|
|
211
|
+
* synthesizing a zero-step candidate that `usePulseXConversionRoutes` (the user
|
|
212
|
+
* interface's plural composer) can consume unchanged, producing the correct
|
|
213
|
+
* same-chain conversion route so the ranker can pick the cheapest option.
|
|
214
|
+
*
|
|
215
|
+
* The synthetic quote carries zero steps (no aggregator hops), a zero execution
|
|
216
|
+
* duration (the direct crossing needs no quote wait), and a null transaction
|
|
217
|
+
* request — this candidate is DISPLAY and RANKING only. The candidate's
|
|
218
|
+
* `deliveredAmount` is net of the omnibridge crossing fee, identical to the math
|
|
219
|
+
* {@link useAggregatorRouteCandidate} applies.
|
|
220
|
+
*
|
|
221
|
+
* This is a PURE exported helper (no hooks, no side effects) so it is
|
|
222
|
+
* unit-testable in isolation and can be called from two `useMemo` blocks in
|
|
223
|
+
* Bridge.tsx without duplicating the object literal.
|
|
224
|
+
*
|
|
225
|
+
* EXECUTION: when the route built from this candidate is selected, the
|
|
226
|
+
* consolidated (aggregator) execute path is deliberately NOT used — there is no
|
|
227
|
+
* aggregator leg for it to sign. `executesViaConsolidated`
|
|
228
|
+
* (`packages/ui/src/lib/state/bridgeExecution.ts`) recognizes the candidate's
|
|
229
|
+
* `entryChainId === originChainId` and routes the selection through the direct
|
|
230
|
+
* omnibridge sender instead, which builds its transaction from the live
|
|
231
|
+
* `useBridgeSettings` cascade rather than from this synthetic quote.
|
|
232
|
+
*
|
|
233
|
+
* @param inputs - the entry chain, origin/destination tokens, amount, and fee rate
|
|
234
|
+
* @returns the synthesized RouteCandidate, or throws when the entry chain is not
|
|
235
|
+
* a valid omnibridge entry point (caller must guard on `omnibridgeProviderForEntryChain`)
|
|
236
|
+
*/
|
|
237
|
+
export declare const buildDirectCrossingCandidate: ({ entryChainId, originChainId, originToken, destinationToken, amountIn, originUsdPrice, destinationUsdPrice, omnibridgeFeePerEther, }: DirectCrossingCandidateInputs) => RouteCandidate;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { formatUnits } from 'viem';
|
|
2
|
+
import { netDeliveredAmount } from './amounts.js';
|
|
3
|
+
import { omnibridgeProviderForEntryChain } from './providers.js';
|
|
4
|
+
/**
|
|
5
|
+
* Synthesizes a {@link RouteCandidate} for the SAME-CHAIN direct-omnibridge
|
|
6
|
+
* conversion case: when the origin chain IS one of the omnibridge entry chains
|
|
7
|
+
* (Ethereum chain 1 or Binance Smart Chain chain 56), there is no aggregator leg
|
|
8
|
+
* to quote — the user bridges directly from that chain to PulseChain. The
|
|
9
|
+
* same-chain skip in {@link useAggregatorRouteCandidate} is correct (nothing to
|
|
10
|
+
* quote), but it left the conversion path empty. This helper fills that gap by
|
|
11
|
+
* synthesizing a zero-step candidate that `usePulseXConversionRoutes` (the user
|
|
12
|
+
* interface's plural composer) can consume unchanged, producing the correct
|
|
13
|
+
* same-chain conversion route so the ranker can pick the cheapest option.
|
|
14
|
+
*
|
|
15
|
+
* The synthetic quote carries zero steps (no aggregator hops), a zero execution
|
|
16
|
+
* duration (the direct crossing needs no quote wait), and a null transaction
|
|
17
|
+
* request — this candidate is DISPLAY and RANKING only. The candidate's
|
|
18
|
+
* `deliveredAmount` is net of the omnibridge crossing fee, identical to the math
|
|
19
|
+
* {@link useAggregatorRouteCandidate} applies.
|
|
20
|
+
*
|
|
21
|
+
* This is a PURE exported helper (no hooks, no side effects) so it is
|
|
22
|
+
* unit-testable in isolation and can be called from two `useMemo` blocks in
|
|
23
|
+
* Bridge.tsx without duplicating the object literal.
|
|
24
|
+
*
|
|
25
|
+
* EXECUTION: when the route built from this candidate is selected, the
|
|
26
|
+
* consolidated (aggregator) execute path is deliberately NOT used — there is no
|
|
27
|
+
* aggregator leg for it to sign. `executesViaConsolidated`
|
|
28
|
+
* (`packages/ui/src/lib/state/bridgeExecution.ts`) recognizes the candidate's
|
|
29
|
+
* `entryChainId === originChainId` and routes the selection through the direct
|
|
30
|
+
* omnibridge sender instead, which builds its transaction from the live
|
|
31
|
+
* `useBridgeSettings` cascade rather than from this synthetic quote.
|
|
32
|
+
*
|
|
33
|
+
* @param inputs - the entry chain, origin/destination tokens, amount, and fee rate
|
|
34
|
+
* @returns the synthesized RouteCandidate, or throws when the entry chain is not
|
|
35
|
+
* a valid omnibridge entry point (caller must guard on `omnibridgeProviderForEntryChain`)
|
|
36
|
+
*/
|
|
37
|
+
export const buildDirectCrossingCandidate = ({ entryChainId, originChainId, originToken, destinationToken, amountIn, originUsdPrice, destinationUsdPrice, omnibridgeFeePerEther, }) => {
|
|
38
|
+
const provider = omnibridgeProviderForEntryChain(entryChainId);
|
|
39
|
+
if (provider === null) {
|
|
40
|
+
throw new Error(`buildDirectCrossingCandidate: chain ${entryChainId} is not an omnibridge entry point`);
|
|
41
|
+
}
|
|
42
|
+
if (originChainId !== entryChainId) {
|
|
43
|
+
throw new Error(`buildDirectCrossingCandidate: originChainId must equal entryChainId (same-chain crossing only)`);
|
|
44
|
+
}
|
|
45
|
+
const delivered = netDeliveredAmount(amountIn, omnibridgeFeePerEther);
|
|
46
|
+
const omnibridgeFeeAmount = amountIn > delivered ? amountIn - delivered : 0n;
|
|
47
|
+
const fromAmountUsd = originUsdPrice !== null && amountIn > 0n
|
|
48
|
+
? String(Number(formatUnits(amountIn, originToken.decimals)) * originUsdPrice)
|
|
49
|
+
: null;
|
|
50
|
+
const quoteId = `direct-omnibridge-${entryChainId}-${originChainId}`;
|
|
51
|
+
const syntheticQuote = {
|
|
52
|
+
// The synthetic quote wraps the omnibridge provider slug. ConsolidatedQuote's
|
|
53
|
+
// `provider` field is typed for the aggregator providers ('lifi' | 'relay'),
|
|
54
|
+
// but the functions that read it (`resolveProviderDisplayName`,
|
|
55
|
+
// `resolveProviderLogoUri`) accept any string at runtime. The cast is safe here
|
|
56
|
+
// because no aggregator-specific code path runs on a zero-step candidate —
|
|
57
|
+
// this synthetic quote is never itself signed; see the module doc comment
|
|
58
|
+
// above for where execution actually happens for the route built from it.
|
|
59
|
+
provider: provider,
|
|
60
|
+
quoteId,
|
|
61
|
+
tool: provider,
|
|
62
|
+
toolName: provider,
|
|
63
|
+
fromAmount: amountIn,
|
|
64
|
+
fromAmountUsd,
|
|
65
|
+
approvalAddress: null,
|
|
66
|
+
executionDurationSeconds: 0,
|
|
67
|
+
steps: [],
|
|
68
|
+
// A direct crossing carries no aggregator, so there is no carrier fee to
|
|
69
|
+
// report. The omnibridge's own crossing fee is `omnibridgeFeeAmount`
|
|
70
|
+
// beside it, which the route surfaces separately.
|
|
71
|
+
fees: [],
|
|
72
|
+
originDeposit: {
|
|
73
|
+
ecosystem: 'evm',
|
|
74
|
+
to: '0x0000000000000000000000000000000000000000',
|
|
75
|
+
data: '0x',
|
|
76
|
+
value: 0n,
|
|
77
|
+
chainId: originChainId,
|
|
78
|
+
gasLimit: null,
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
return {
|
|
82
|
+
id: quoteId,
|
|
83
|
+
quote: syntheticQuote,
|
|
84
|
+
omnibridgeProvider: provider,
|
|
85
|
+
entryChainId,
|
|
86
|
+
originToken,
|
|
87
|
+
destinationToken,
|
|
88
|
+
deliveredAmount: delivered,
|
|
89
|
+
omnibridgeFeeAmount,
|
|
90
|
+
destinationUsdPrice,
|
|
91
|
+
// A same-chain crossing has no aggregator leg to solve backward, so it spends
|
|
92
|
+
// exactly what was typed — requested and spent are the same figure by
|
|
93
|
+
// construction, and the route reports nothing unspent.
|
|
94
|
+
requestedAmount: amountIn,
|
|
95
|
+
};
|
|
96
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What answering one carrier's ask produces: a deliverable amount, or a
|
|
3
|
+
* refusal. Declared LOCALLY, rather than imported, so gibs's own carriers
|
|
4
|
+
* (`omnibridge.ts`, `pulsex.ts`) can pin their `ask` function's return type
|
|
5
|
+
* without `bridge-sdk` depending on `@gibs/quotes` — see
|
|
6
|
+
* `@gibs/quotes/types`'s own doc on why that dependency would be circular.
|
|
7
|
+
*
|
|
8
|
+
* STRUCTURALLY IDENTICAL to `@gibs/quotes`'s `CarrierAskAnswer` (itself an
|
|
9
|
+
* alias of `search/waves.ts`'s `AskEdgeAnswer`) — every field name and type
|
|
10
|
+
* matches exactly, which is what lets an object shaped like this satisfy
|
|
11
|
+
* `Carrier.ask`'s return type wherever a caller that imports both packages
|
|
12
|
+
* (`packages/ui`) assigns one of these carriers into a `Carrier[]` list. This
|
|
13
|
+
* file is the ONE place that shape is spelled out in `bridge-sdk`; every
|
|
14
|
+
* carrier factory here imports this type rather than re-declaring it.
|
|
15
|
+
*/
|
|
16
|
+
export type CarrierAskAnswer = {
|
|
17
|
+
readonly ok: true;
|
|
18
|
+
/** What the edge delivers for the asked input, in `edge.to`'s base units. */
|
|
19
|
+
readonly deliveredAmount: bigint;
|
|
20
|
+
/** The GUARANTEED delivered amount after slippage, when known; null when not. */
|
|
21
|
+
readonly minimumDeliveredAmount: bigint | null;
|
|
22
|
+
/** The carrier's own claimed execution duration in seconds, or null. */
|
|
23
|
+
readonly claimedDurationSeconds: number | null;
|
|
24
|
+
} | {
|
|
25
|
+
readonly ok: false;
|
|
26
|
+
readonly refusal: {
|
|
27
|
+
readonly kind: 'no-quote' | 'could-not-ask' | 'cannot-carry' | 'below-minimum' | 'above-available';
|
|
28
|
+
/** The carrier's own words for why, or null when none was given. */
|
|
29
|
+
readonly reason: string | null;
|
|
30
|
+
/** A minimum amount this refusal names, in `edge.from`'s base units, or null. */
|
|
31
|
+
readonly minimumAmount: bigint | null;
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* What answering one carrier's SYNCHRONOUS, EXACT read produces for one edge
|
|
36
|
+
* at one input amount: a delivered amount, or a refusal. Declared LOCALLY for
|
|
37
|
+
* the same reason {@link CarrierAskAnswer} is — see that type's own doc.
|
|
38
|
+
*
|
|
39
|
+
* STRUCTURALLY IDENTICAL to `@gibs/quotes`'s `ExactHopResult`. `'refused'` is
|
|
40
|
+
* a REAL answer (the carrier's own local read says this amount cannot
|
|
41
|
+
* cross), distinct from the bare `null` a carrier's `exact` method may also
|
|
42
|
+
* return for an edge it has nothing to say about (its `prepare` was never
|
|
43
|
+
* called, or this edge fell outside what it read).
|
|
44
|
+
*/
|
|
45
|
+
export type CarrierExactResult = {
|
|
46
|
+
readonly outcome: 'delivered';
|
|
47
|
+
/** What this edge delivers for exactly the requested input amount, in `edge.to`'s base units. */
|
|
48
|
+
readonly deliveredAmount: bigint;
|
|
49
|
+
/** How far this edge's executed rate falls below its marginal rate, in percent; absent when the carrier cannot measure it. */
|
|
50
|
+
readonly priceImpactPercent?: number;
|
|
51
|
+
} | {
|
|
52
|
+
readonly outcome: 'refused';
|
|
53
|
+
readonly refusal: {
|
|
54
|
+
readonly kind: 'no-quote' | 'could-not-ask' | 'cannot-carry' | 'below-minimum' | 'above-available';
|
|
55
|
+
/** The carrier's own words for why, or null when none was given. */
|
|
56
|
+
readonly reason: string | null;
|
|
57
|
+
/** A minimum amount this refusal names, in `edge.from`'s base units, or null. */
|
|
58
|
+
readonly minimumAmount: bigint | null;
|
|
59
|
+
};
|
|
60
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import type { PublicClient } from 'viem';
|
|
2
|
+
import { type EntryLimits } from '../../bridge-limits.js';
|
|
3
|
+
import type { Token } from '../../types.js';
|
|
4
|
+
import { type AssetNode, type HopEdge } from '../search/graph.js';
|
|
5
|
+
import type { CarrierAskAnswer, CarrierExactResult } from './ask-answer.js';
|
|
6
|
+
/**
|
|
7
|
+
* The omnibridge crossing (`'pulsechain'` — the Ethereum entry — and
|
|
8
|
+
* `'tokensex'` — the Binance Smart Chain entry) as a plug-in `Carrier` for
|
|
9
|
+
* `@gibs/quotes`'s route-search engine. GIBS-SPECIFIC — see
|
|
10
|
+
* `docs/quote-service.md`'s "Carriers" section: "never built in ... the
|
|
11
|
+
* omnibridge crossing." Registered from `packages/ui/src/lib/state/useRouteSearch.ts`
|
|
12
|
+
* / `route-search-quotes.ts`.
|
|
13
|
+
*
|
|
14
|
+
* This module returns a plain object shaped like `@gibs/quotes`'s `Carrier`
|
|
15
|
+
* type WITHOUT importing it — `bridge-sdk` cannot depend on `@gibs/quotes`
|
|
16
|
+
* (see `@gibs/quotes/types`'s own doc on the circular-dependency reason).
|
|
17
|
+
* `HopEdge`/`AssetNode`/`AskEdgeAnswer` here are the SAME declarations that
|
|
18
|
+
* package's `CarrierHopEdge`/`CarrierAssetNode`/`CarrierAskAnswer` alias, so
|
|
19
|
+
* the object is structurally identical to a `Carrier` wherever a caller that
|
|
20
|
+
* imports both packages assigns it into one.
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* One token the omnibridge bridges between its entry chain (Ethereum or
|
|
24
|
+
* Binance Smart Chain today; a testnet entry chain under `testnetPathways`)
|
|
25
|
+
* and PulseChain.
|
|
26
|
+
*
|
|
27
|
+
* NAMED `entryChainToken`, NOT `ethereumToken`. The UI's own
|
|
28
|
+
* `ConsolidatedDestinationPair` (`packages/ui/src/lib/stores/consolidated-tokens.ts`)
|
|
29
|
+
* keeps the older name for its Ethereum-only history; this module reuses its
|
|
30
|
+
* shape, not its name, because a Binance Smart Chain pair routed through the
|
|
31
|
+
* same field would otherwise carry an Ethereum-shaped name for a token that
|
|
32
|
+
* never touches Ethereum.
|
|
33
|
+
*/
|
|
34
|
+
export type BridgeablePair = {
|
|
35
|
+
/** The token on the omnibridge's entry chain. */
|
|
36
|
+
readonly entryChainToken: Token;
|
|
37
|
+
/** That token's PulseChain-side representation. */
|
|
38
|
+
readonly pulsechainToken: Token;
|
|
39
|
+
/** The entry chain's decimal chain id — the chain `entryChainToken` lives on. */
|
|
40
|
+
readonly entryChainId: number;
|
|
41
|
+
};
|
|
42
|
+
/** What {@link createOmnibridgeCarrier} needs. */
|
|
43
|
+
export type CreateOmnibridgeCarrierOptions = {
|
|
44
|
+
/** Every token pair the omnibridge bridges, entry chain by entry chain. */
|
|
45
|
+
readonly bridgeablePairs: readonly BridgeablePair[];
|
|
46
|
+
/** Whether this is a production build — see `pathway()`'s own `isProd`. */
|
|
47
|
+
readonly isProductionNetwork: boolean;
|
|
48
|
+
/** Reads the entry mediator's bounds for one bridge-crossing edge — a free, local read. */
|
|
49
|
+
readonly readEntryLimits: (edge: HopEdge) => Promise<EntryLimits | null>;
|
|
50
|
+
/** Reads the omnibridge's own fee rate (per ether) for one bridge-crossing edge, in whichever direction it runs. */
|
|
51
|
+
readonly readFeePerEther: (edge: HopEdge) => Promise<bigint | null>;
|
|
52
|
+
/**
|
|
53
|
+
* Returns a client for a chain id, for {@link Carrier.prepare}'s own
|
|
54
|
+
* batched multicall reads — never called by `ask`, which keeps using
|
|
55
|
+
* {@link readEntryLimits}/{@link readFeePerEther} unchanged.
|
|
56
|
+
*
|
|
57
|
+
* OPTIONAL, ON PURPOSE. A host that has not wired a client lookup yet gets
|
|
58
|
+
* the carrier's original behavior: `prepare` is a no-op and `exact` always
|
|
59
|
+
* returns `null`, so `enumerate.ts` falls through to `estimate`/the
|
|
60
|
+
* price-feed default exactly as it did before either method existed.
|
|
61
|
+
*
|
|
62
|
+
* @param chainId - the chain a batched read needs a client for
|
|
63
|
+
* @returns a client, or null when this host has none for that chain
|
|
64
|
+
*/
|
|
65
|
+
readonly clientForChain?: (chainId: number) => PublicClient | null;
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Builds the omnibridge crossing as a plug-in carrier.
|
|
69
|
+
*
|
|
70
|
+
* @param options - see {@link CreateOmnibridgeCarrierOptions}
|
|
71
|
+
* @returns the carrier — `id: 'omnibridge'`; every EDGE it offers carries the
|
|
72
|
+
* real `'pulsechain'`/`'tokensex'` provider id, since one registration can
|
|
73
|
+
* speak for either entry chain depending on the pair
|
|
74
|
+
*/
|
|
75
|
+
export declare const createOmnibridgeCarrier: (options: CreateOmnibridgeCarrierOptions) => {
|
|
76
|
+
id: string;
|
|
77
|
+
edgesFrom: (from: AssetNode, to: AssetNode) => readonly HopEdge[];
|
|
78
|
+
ask: ({ edge, inputAmount }: {
|
|
79
|
+
edge: HopEdge;
|
|
80
|
+
inputAmount: bigint;
|
|
81
|
+
}) => Promise<CarrierAskAnswer>;
|
|
82
|
+
prepare: (nodes: readonly AssetNode[]) => Promise<void>;
|
|
83
|
+
exact: (edge: HopEdge, amountIn: bigint) => CarrierExactResult | null;
|
|
84
|
+
isRateLimited: boolean;
|
|
85
|
+
depositMode: "wallet-signed";
|
|
86
|
+
sender: "omnibridge";
|
|
87
|
+
settlementSeconds: number;
|
|
88
|
+
};
|
|
89
|
+
/** What {@link withOmnibridgeEntryFusing}'s `fusesWithNext` is asked — structurally `@gibs/quotes`'s `CarrierFusesWithNextOptions`. */
|
|
90
|
+
export type OmnibridgeFuseQuestion = {
|
|
91
|
+
/** What the acting (provider) hop spends. */
|
|
92
|
+
readonly hopFrom: AssetNode;
|
|
93
|
+
/** The carrier of the hop that follows. */
|
|
94
|
+
readonly nextHopCarrier: string;
|
|
95
|
+
/** What the following hop spends — where the provider hop lands. */
|
|
96
|
+
readonly nextHopFrom: AssetNode;
|
|
97
|
+
/** Where the following hop delivers. */
|
|
98
|
+
readonly nextHopDestinationChainId: number;
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* Wraps ANY carrier-shaped object (built-in or a host's own) with the
|
|
102
|
+
* omnibridge's OWN fuse rule: whether THIS carrier's execution, landing on
|
|
103
|
+
* arrival, also performs the omnibridge's entry call — so the two hops
|
|
104
|
+
* together cost the reader one signature instead of two.
|
|
105
|
+
*
|
|
106
|
+
* EVERY CONDITION IS A FACT THE PROVIDER'S OWN DESCRIPTOR STATES
|
|
107
|
+
* (`../../providers.ts`), never a name compared here:
|
|
108
|
+
*
|
|
109
|
+
* - it executes destination calls at all (`executesDestinationCalls` — true
|
|
110
|
+
* for LI.FI and Relay, false for NEAR Intents, which delivers to the
|
|
111
|
+
* reader's own wallet and stops);
|
|
112
|
+
* - it can do so FROM this hop's origin chain (`destinationCallOriginChainIds`
|
|
113
|
+
* — LI.FI's contract-calls endpoint is Ethereum only, so from Base or
|
|
114
|
+
* Arbitrum a LI.FI hop is an unfused delivery followed by a crossing the
|
|
115
|
+
* reader signs);
|
|
116
|
+
* - when the entry is the omnibridge's NATIVE one (the provider lands a
|
|
117
|
+
* native coin, and `wrapAndRelayTokens` is payable), it can attach value to
|
|
118
|
+
* the call (`destinationCallCarriesNativeValue`);
|
|
119
|
+
* - and the next hop really IS the omnibridge entry, landing on PulseChain
|
|
120
|
+
* (`relayTokens`/`wrapAndRelayTokens` both MINT there; any other
|
|
121
|
+
* destination is the omnibridge's OUTBOUND leg, which no arrival can make).
|
|
122
|
+
*
|
|
123
|
+
* THIS IS THE ONE PLACE `'pulsechain'`/`'tokensex'`/PulseChain'S CHAIN ID
|
|
124
|
+
* APPEAR IN A `fusesWithNext` CALLBACK — gibs's own registration
|
|
125
|
+
* (`packages/ui/src/lib/state/useRouteSearch.ts`) wraps `createLifiCarrier`/
|
|
126
|
+
* `createRelayCarrier` with this before registering them, so the generic
|
|
127
|
+
* search engine (`@gibs/quotes`'s `capabilities.ts`) never has to know what
|
|
128
|
+
* "the bridge" means.
|
|
129
|
+
*
|
|
130
|
+
* @param carrier - the carrier to wrap; its own shape is preserved, only `fusesWithNext` is added/replaced
|
|
131
|
+
* @returns the same carrier, with a `fusesWithNext` that recognizes the omnibridge entry call
|
|
132
|
+
*/
|
|
133
|
+
export declare const withOmnibridgeEntryFusing: <T extends {
|
|
134
|
+
readonly id: string;
|
|
135
|
+
}>(carrier: T) => T & {
|
|
136
|
+
readonly fusesWithNext: (nextHop: OmnibridgeFuseQuestion) => boolean;
|
|
137
|
+
};
|