@gibs/bridge-sdk 1.13.0 → 1.17.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 (217) hide show
  1. package/README.md +244 -18
  2. package/abis/package.json +6 -0
  3. package/bridge-limits/package.json +6 -0
  4. package/chain-info/package.json +6 -0
  5. package/chain-names/package.json +6 -0
  6. package/chains/package.json +6 -0
  7. package/claims/package.json +6 -0
  8. package/config/package.json +6 -0
  9. package/consolidated-quote/package.json +6 -0
  10. package/destination-calldata/package.json +6 -0
  11. package/dist/chain-info.d.ts +1 -1
  12. package/dist/chain-info.js +11 -12
  13. package/dist/chains.d.ts +25 -0
  14. package/dist/chains.js +55 -20
  15. package/dist/cjs/abis.d.ts +1 -0
  16. package/dist/cjs/abis.js +19 -0
  17. package/dist/cjs/bridge-limits.d.ts +103 -0
  18. package/dist/cjs/bridge-limits.js +89 -0
  19. package/dist/cjs/chain-info.d.ts +169 -0
  20. package/dist/cjs/chain-info.js +452 -0
  21. package/dist/cjs/chain-names.d.ts +160 -0
  22. package/dist/cjs/chain-names.js +207 -0
  23. package/dist/cjs/chains.d.ts +90 -0
  24. package/dist/cjs/chains.js +357 -0
  25. package/dist/cjs/claims.d.ts +198 -0
  26. package/dist/cjs/claims.js +182 -0
  27. package/dist/cjs/config.d.ts +240 -0
  28. package/dist/cjs/config.js +537 -0
  29. package/dist/cjs/consolidated-quote.d.ts +648 -0
  30. package/dist/cjs/consolidated-quote.js +1048 -0
  31. package/dist/cjs/destination-calldata.d.ts +118 -0
  32. package/dist/cjs/destination-calldata.js +156 -0
  33. package/dist/cjs/ecosystems.d.ts +217 -0
  34. package/dist/cjs/ecosystems.js +298 -0
  35. package/dist/cjs/execution.d.ts +346 -0
  36. package/dist/cjs/execution.js +468 -0
  37. package/dist/cjs/fee-type.d.ts +10 -0
  38. package/dist/cjs/fee-type.js +10 -0
  39. package/dist/cjs/hyperliquid-execution.d.ts +152 -0
  40. package/dist/cjs/hyperliquid-execution.js +175 -0
  41. package/dist/cjs/image-links.d.ts +117 -0
  42. package/dist/cjs/image-links.js +153 -0
  43. package/dist/cjs/index.d.ts +23 -0
  44. package/dist/cjs/index.js +39 -0
  45. package/dist/cjs/lifi-execution-guard.d.ts +210 -0
  46. package/dist/cjs/lifi-execution-guard.js +409 -0
  47. package/dist/cjs/near-intents-conformance.d.ts +85 -0
  48. package/dist/cjs/near-intents-conformance.js +337 -0
  49. package/dist/cjs/near-intents-route.d.ts +47 -0
  50. package/dist/cjs/near-intents-route.js +303 -0
  51. package/dist/cjs/near-intents.d.ts +524 -0
  52. package/dist/cjs/near-intents.js +1071 -0
  53. package/dist/cjs/origin-deposit.d.ts +326 -0
  54. package/dist/cjs/origin-deposit.js +82 -0
  55. package/dist/cjs/package.json +3 -0
  56. package/dist/cjs/pre-quote.d.ts +198 -0
  57. package/dist/cjs/pre-quote.js +180 -0
  58. package/dist/cjs/prices.d.ts +107 -0
  59. package/dist/cjs/prices.js +172 -0
  60. package/dist/cjs/providers.d.ts +238 -0
  61. package/dist/cjs/providers.js +171 -0
  62. package/dist/cjs/quote-fees.d.ts +102 -0
  63. package/dist/cjs/quote-fees.js +201 -0
  64. package/dist/cjs/referral.d.ts +85 -0
  65. package/dist/cjs/referral.js +85 -0
  66. package/dist/cjs/relay-currencies.d.ts +47 -0
  67. package/dist/cjs/relay-currencies.js +95 -0
  68. package/dist/cjs/relay-depository.d.ts +2 -0
  69. package/dist/cjs/relay-depository.js +85 -0
  70. package/dist/cjs/relay-quote.d.ts +301 -0
  71. package/dist/cjs/relay-quote.js +996 -0
  72. package/dist/cjs/route-steps.d.ts +138 -0
  73. package/dist/cjs/route-steps.js +310 -0
  74. package/dist/cjs/routing/amounts.d.ts +80 -0
  75. package/dist/cjs/routing/amounts.js +126 -0
  76. package/dist/cjs/routing/candidate-route.d.ts +43 -0
  77. package/dist/cjs/routing/candidate-route.js +50 -0
  78. package/dist/cjs/routing/candidate.d.ts +237 -0
  79. package/dist/cjs/routing/candidate.js +100 -0
  80. package/dist/cjs/routing/carriers/ask-answer.d.ts +77 -0
  81. package/dist/cjs/routing/carriers/ask-answer.js +2 -0
  82. package/dist/cjs/routing/carriers/omnibridge.d.ts +137 -0
  83. package/dist/cjs/routing/carriers/omnibridge.js +459 -0
  84. package/dist/cjs/routing/carriers/pulsex-paths.d.ts +80 -0
  85. package/dist/cjs/routing/carriers/pulsex-paths.js +97 -0
  86. package/dist/cjs/routing/carriers/pulsex-split.d.ts +175 -0
  87. package/dist/cjs/routing/carriers/pulsex-split.js +193 -0
  88. package/dist/cjs/routing/carriers/pulsex.d.ts +159 -0
  89. package/dist/cjs/routing/carriers/pulsex.js +565 -0
  90. package/dist/cjs/routing/carriers/wrap.d.ts +25 -0
  91. package/dist/cjs/routing/carriers/wrap.js +119 -0
  92. package/dist/cjs/routing/composed-route-quality.d.ts +125 -0
  93. package/dist/cjs/routing/composed-route-quality.js +144 -0
  94. package/dist/cjs/routing/entry-chain-anchor.d.ts +88 -0
  95. package/dist/cjs/routing/entry-chain-anchor.js +59 -0
  96. package/dist/cjs/routing/format.d.ts +31 -0
  97. package/dist/cjs/routing/format.js +64 -0
  98. package/dist/cjs/routing/index.d.ts +38 -0
  99. package/dist/cjs/routing/index.js +134 -0
  100. package/dist/cjs/routing/producers.d.ts +770 -0
  101. package/dist/cjs/routing/producers.js +1617 -0
  102. package/dist/cjs/routing/providers.d.ts +31 -0
  103. package/dist/cjs/routing/providers.js +48 -0
  104. package/dist/cjs/routing/route-data.d.ts +355 -0
  105. package/dist/cjs/routing/route-data.js +2 -0
  106. package/dist/cjs/routing/search/compose.d.ts +168 -0
  107. package/dist/cjs/routing/search/compose.js +104 -0
  108. package/dist/cjs/routing/search/graph.d.ts +668 -0
  109. package/dist/cjs/routing/search/graph.js +461 -0
  110. package/dist/cjs/routing/search/plan-route-data.d.ts +269 -0
  111. package/dist/cjs/routing/search/plan-route-data.js +848 -0
  112. package/dist/cjs/routing/search/score.d.ts +356 -0
  113. package/dist/cjs/routing/search/score.js +445 -0
  114. package/dist/cjs/routing/swap-transactions.d.ts +91 -0
  115. package/dist/cjs/routing/swap-transactions.js +131 -0
  116. package/dist/cjs/routing/usd-value.d.ts +17 -0
  117. package/dist/cjs/routing/usd-value.js +29 -0
  118. package/dist/cjs/settings.d.ts +785 -0
  119. package/dist/cjs/settings.js +1074 -0
  120. package/dist/cjs/ton-connect.d.ts +98 -0
  121. package/dist/cjs/ton-connect.js +206 -0
  122. package/dist/cjs/ton-execution.d.ts +7 -0
  123. package/dist/cjs/ton-execution.js +23 -0
  124. package/dist/cjs/ton.d.ts +37 -0
  125. package/dist/cjs/ton.js +83 -0
  126. package/dist/cjs/tron-execution.d.ts +146 -0
  127. package/dist/cjs/tron-execution.js +248 -0
  128. package/dist/cjs/types.d.ts +51 -0
  129. package/dist/cjs/types.js +2 -0
  130. package/dist/claims.d.ts +198 -0
  131. package/dist/claims.js +140 -0
  132. package/dist/config.d.ts +24 -0
  133. package/dist/config.js +39 -5
  134. package/dist/consolidated-quote.d.ts +109 -15
  135. package/dist/consolidated-quote.js +310 -52
  136. package/dist/execution.d.ts +346 -0
  137. package/dist/execution.js +428 -0
  138. package/dist/hyperliquid-execution.js +2 -3
  139. package/dist/index.d.ts +3 -0
  140. package/dist/index.js +3 -0
  141. package/dist/lifi-execution-guard.d.ts +13 -2
  142. package/dist/lifi-execution-guard.js +4 -0
  143. package/dist/near-intents.js +2 -3
  144. package/dist/pre-quote.d.ts +6 -6
  145. package/dist/pre-quote.js +10 -14
  146. package/dist/providers.d.ts +17 -0
  147. package/dist/providers.js +6 -0
  148. package/dist/referral.d.ts +12 -4
  149. package/dist/referral.js +12 -4
  150. package/dist/relay-depository.d.ts +2 -0
  151. package/dist/relay-depository.js +82 -0
  152. package/dist/relay-quote.js +2 -3
  153. package/dist/routing/candidate.d.ts +3 -3
  154. package/dist/routing/candidate.js +3 -3
  155. package/dist/routing/carriers/ask-answer.d.ts +19 -0
  156. package/dist/routing/carriers/omnibridge.js +23 -21
  157. package/dist/routing/carriers/pulsex-paths.d.ts +80 -0
  158. package/dist/routing/carriers/pulsex-paths.js +92 -0
  159. package/dist/routing/carriers/pulsex-split.d.ts +175 -0
  160. package/dist/routing/carriers/pulsex-split.js +185 -0
  161. package/dist/routing/carriers/pulsex.d.ts +69 -21
  162. package/dist/routing/carriers/pulsex.js +184 -65
  163. package/dist/routing/composed-route-quality.d.ts +28 -6
  164. package/dist/routing/composed-route-quality.js +36 -5
  165. package/dist/routing/entry-chain-anchor.d.ts +1 -1
  166. package/dist/routing/entry-chain-anchor.js +1 -1
  167. package/dist/routing/index.d.ts +7 -3
  168. package/dist/routing/index.js +7 -3
  169. package/dist/routing/producers.js +1 -1
  170. package/dist/routing/providers.d.ts +5 -0
  171. package/dist/routing/providers.js +5 -0
  172. package/dist/routing/search/graph.d.ts +29 -0
  173. package/dist/routing/search/plan-route-data.d.ts +25 -0
  174. package/dist/routing/search/plan-route-data.js +43 -7
  175. package/dist/routing/search/score.d.ts +33 -1
  176. package/dist/routing/search/score.js +41 -6
  177. package/dist/routing/swap-transactions.d.ts +91 -0
  178. package/dist/routing/swap-transactions.js +125 -0
  179. package/dist/settings.d.ts +94 -1
  180. package/dist/settings.js +95 -3
  181. package/dist/ton-connect.d.ts +98 -0
  182. package/dist/ton-connect.js +200 -0
  183. package/dist/ton-execution.d.ts +4 -114
  184. package/dist/ton-execution.js +4 -244
  185. package/dist/ton.d.ts +37 -0
  186. package/dist/ton.js +65 -0
  187. package/docs/examples/example-a-ether-to-pulse.ts +300 -0
  188. package/docs/examples/example-b-token-pulsechain-to-ethereum.ts +270 -0
  189. package/docs/examples/shared.ts +261 -0
  190. package/docs/examples/tsconfig.json +18 -0
  191. package/docs/integration-guide.md +617 -0
  192. package/ecosystems/package.json +6 -0
  193. package/execution/package.json +6 -0
  194. package/fee-type/package.json +6 -0
  195. package/hyperliquid-execution/package.json +6 -0
  196. package/image-links/package.json +6 -0
  197. package/lifi-execution-guard/package.json +6 -0
  198. package/llms.txt +234 -0
  199. package/near-intents/package.json +6 -0
  200. package/near-intents-route/package.json +6 -0
  201. package/origin-deposit/package.json +6 -0
  202. package/package.json +818 -10
  203. package/pre-quote/package.json +6 -0
  204. package/prices/package.json +6 -0
  205. package/providers/package.json +6 -0
  206. package/quote-fees/package.json +6 -0
  207. package/referral/package.json +6 -0
  208. package/relay-currencies/package.json +6 -0
  209. package/relay-quote/package.json +6 -0
  210. package/route-steps/package.json +6 -0
  211. package/routing/package.json +6 -0
  212. package/settings/package.json +6 -0
  213. package/ton/package.json +6 -0
  214. package/ton-connect/package.json +6 -0
  215. package/ton-execution/package.json +6 -0
  216. package/tron-execution/package.json +6 -0
  217. package/types/package.json +6 -0
@@ -0,0 +1,303 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.describeDeferredCrossing = exports.buildNearIntentsTwoStepRouteData = void 0;
37
+ const imageLinks = __importStar(require("./image-links.js"));
38
+ const producers_js_1 = require("./routing/producers.js");
39
+ const providers_js_1 = require("./providers.js");
40
+ const usd_value_js_1 = require("./routing/usd-value.js");
41
+ const chain_names_js_1 = require("./chain-names.js");
42
+ /**
43
+ * The route shape for an aggregator that cannot execute on the chain it
44
+ * delivers to.
45
+ *
46
+ * WHY THIS EXISTS AT ALL. Every other consolidated route in this repository is
47
+ * ONE signature: the aggregator carries the reader's funds to an omnibridge
48
+ * entry chain and its executor performs the entry call on arrival, so the
49
+ * crossing into PulseChain happens inside the same transaction the reader
50
+ * already signed. NEAR Intents cannot do that — it delivers tokens to an
51
+ * address and runs nothing — and no arrangement of recipients works around it,
52
+ * because every omnibridge entry point learns who the reader is from a data
53
+ * field and a plain token transfer has none. See the head of `near-intents.ts`.
54
+ *
55
+ * So the crossing becomes TWO signatures, and the honest thing is to draw it
56
+ * that way. The aggregator lands the anchor token in the reader's OWN wallet on
57
+ * the entry chain; the reader then signs the ordinary omnibridge call
58
+ * themselves. The interface already renders exactly this shape — a section
59
+ * marked `deferred` draws "You sign this later" on the route itself rather than
60
+ * hiding the fact in a tooltip — so nothing new had to be invented to show it.
61
+ *
62
+ * WHAT THIS MUST NEVER DO is present the second signature as optional, or let
63
+ * the route claim a delivered amount as though it were settled. The reader is
64
+ * mid-journey until they sign again, and a route that implies otherwise is
65
+ * selling a single-signature experience it does not deliver.
66
+ */
67
+ /**
68
+ * Turns a token into the display node the route strip draws, resolving its logo
69
+ * here rather than in the view.
70
+ *
71
+ * Pre-resolved deliberately: a view-layer image fallback reaches only the nodes
72
+ * a builder left unset, so a builder that sets the field and a builder that
73
+ * does not produce different pictures for the same token.
74
+ *
75
+ * The chain badge goes through `networkOrPseudo`, not `network` — a deposit-
76
+ * address origin (Zcash) carries a local, invented chain id the numeric
77
+ * endpoint 404s on. See that helper's own note for why this lives in
78
+ * `image-links.ts` rather than the richer client-side resolver.
79
+ */
80
+ const tokenNode = (token, chainId) => ({
81
+ symbol: token.symbol,
82
+ address: token.address,
83
+ chainId,
84
+ decimals: token.decimals,
85
+ // `tokenImageOrChainFallback`, NOT `image` — the ANCHOR node this call also
86
+ // draws can reach here before its exact address is known (the deferred
87
+ // crossing has not settled yet), and `image` either throws on an address it
88
+ // cannot checksum or draws nothing at all. See that helper's own note.
89
+ logoUri: imageLinks.tokenImageOrChainFallback(token),
90
+ chainLogoUri: imageLinks.networkOrPseudo(chainId),
91
+ });
92
+ /**
93
+ * Parses one of the aggregator's own dollar figures.
94
+ *
95
+ * They arrive as decimal strings. A figure that will not parse becomes null
96
+ * rather than zero, because zero is a real value that reads as "this leg is
97
+ * free" — which is the one thing a cost figure must never say by accident.
98
+ */
99
+ const usdNumber = (value) => {
100
+ if (typeof value !== 'string' || value === '') {
101
+ return null;
102
+ }
103
+ const parsed = Number(value);
104
+ return Number.isFinite(parsed) ? parsed : null;
105
+ };
106
+ /**
107
+ * Builds the two-signature route for a candidate whose aggregator cannot
108
+ * execute the omnibridge entry call.
109
+ *
110
+ * The result has exactly two sections, and the order carries the meaning:
111
+ *
112
+ * 1. The aggregator's leg, signed NOW. It ends with the anchor token sitting
113
+ * in the reader's own wallet on the entry chain.
114
+ * 2. The omnibridge crossing, marked `deferred`, signed LATER by the reader.
115
+ *
116
+ * COSTS ARE SPLIT BETWEEN THE SECTIONS RATHER THAN POOLED, because a reader
117
+ * deciding whether to accept a second signature needs to know what each half
118
+ * costs. The first section's spread is the difference between the aggregator's
119
+ * own paid and delivered figures — both from the one answer that priced them,
120
+ * never from two feeds. The second section's cost is the omnibridge crossing
121
+ * fee, computed from the known on-chain rate.
122
+ *
123
+ * THE DELIVERED FIGURE IS AN ESTIMATE AND THE INTERFACE KNOWS IT. A route whose
124
+ * last section is deferred has not been quoted end to end, so
125
+ * `outputAmountIsUnsettled` blanks the received-amount field on the reader's
126
+ * behalf. The figure is still carried — the conversion route sets its estimate
127
+ * the same way — so the route can be ranked and compared.
128
+ *
129
+ * @param candidate - the route candidate, which must carry a `deferredCrossing`
130
+ * @returns the two-section route, or null when the candidate names no deferred
131
+ * crossing or no omnibridge provider to perform it
132
+ */
133
+ const buildNearIntentsTwoStepRouteData = (candidate) => {
134
+ const deferredCrossing = candidate.deferredCrossing;
135
+ if (!deferredCrossing) {
136
+ return null;
137
+ }
138
+ // No omnibridge leg means there is no second signature, which means this is
139
+ // not the shape being built. A route the aggregator carries end to end is an
140
+ // ordinary one-signature route and belongs to `buildCandidateRouteData`.
141
+ const omnibridgeProviderKey = candidate.omnibridgeProvider;
142
+ if (omnibridgeProviderKey === null) {
143
+ return null;
144
+ }
145
+ const { originToken, destinationToken } = candidate;
146
+ const { anchorToken, anchorAmount, anchorUsdValue } = deferredCrossing;
147
+ const originNode = tokenNode(originToken, originToken.chainId);
148
+ const anchorNode = tokenNode(anchorToken, candidate.entryChainId);
149
+ const destinationNode = tokenNode(destinationToken, producers_js_1.pulsechainChainId);
150
+ const paidUsd = usdNumber(candidate.quote.fromAmountUsd);
151
+ const landedUsd = usdNumber(anchorUsdValue);
152
+ // The aggregator's spread on its own leg: what the reader paid, less what the
153
+ // aggregator says arrives. Both figures come from the same answer, so the
154
+ // difference is the route and nothing else.
155
+ const aggregatorFeeUsd = (0, producers_js_1.subtractUsdValues)(paidUsd, landedUsd);
156
+ const crossingFeeUsd = (0, usd_value_js_1.usdValueOfAmount)({
157
+ balance: candidate.omnibridgeFeeAmount,
158
+ decimals: destinationToken.decimals,
159
+ price: candidate.destinationUsdPrice,
160
+ });
161
+ const etaSeconds = candidate.quote.executionDurationSeconds > 0 ? candidate.quote.executionDurationSeconds : null;
162
+ const etaMinutes = candidate.quote.executionDurationSeconds > 0
163
+ ? Math.ceil(candidate.quote.executionDurationSeconds / 60)
164
+ : null;
165
+ const aggregatorHop = {
166
+ // THIS HOP IS THE AGGREGATOR, NOT THE OMNIBRIDGE — `providerDisplayName`
167
+ // (used for the crossing hop below) is keyed only on `Providers.PULSECHAIN`
168
+ // / `Providers.TOKENSEX` and falls back to the generic "Omnibridge" for
169
+ // anything else. Run through it here, `candidate.quote.provider` (a
170
+ // `ProviderId` — 'lifi' | 'relay' | 'near-intents') had no entry, so a
171
+ // NEAR Intents two-step route named its first leg "Omnibridge" — the
172
+ // bridge, not the aggregator that actually carried it. `providerById` is
173
+ // total over `ProviderId` and throws on an unregistered one rather than
174
+ // silently naming a different provider.
175
+ providerName: (0, providers_js_1.providerById)(candidate.quote.provider).label,
176
+ providerKey: candidate.quote.provider,
177
+ title: `Send to ${(0, chain_names_js_1.chainDisplayName)(candidate.entryChainId)}`,
178
+ conversion: `→ ${anchorToken.symbol}`,
179
+ fromToken: originNode,
180
+ toToken: anchorNode,
181
+ feeUsdValue: aggregatorFeeUsd,
182
+ // The reader's own signature starts this leg; nothing runs inside it.
183
+ automatic: false,
184
+ };
185
+ const aggregatorSection = {
186
+ id: `${candidate.id}-signature-1`,
187
+ // Named for where the funds END UP, and pointedly NOT "Bridge to
188
+ // PulseChain": this signature does not reach PulseChain and a label that
189
+ // said so would be the single-signature claim this route exists to avoid.
190
+ label: `Send to ${(0, chain_names_js_1.chainDisplayName)(candidate.entryChainId)}`,
191
+ providerKey: candidate.quote.provider,
192
+ tokenFlow: [originNode, anchorNode],
193
+ // WHAT THE READER IS LEFT HOLDING between the two signatures, in their own
194
+ // wallet on the entry chain. This is the step's whole point.
195
+ landing: {
196
+ amount: anchorAmount,
197
+ decimals: anchorToken.decimals,
198
+ symbol: anchorToken.symbol,
199
+ usdValue: landedUsd,
200
+ },
201
+ feeUsdValue: aggregatorFeeUsd,
202
+ fees: candidate.quote.fees,
203
+ etaMinutes,
204
+ etaSeconds,
205
+ hops: [aggregatorHop],
206
+ };
207
+ const crossingHop = {
208
+ providerName: (0, producers_js_1.providerDisplayName)(omnibridgeProviderKey),
209
+ providerKey: omnibridgeProviderKey,
210
+ title: `Bridge to ${(0, chain_names_js_1.chainDisplayName)(producers_js_1.pulsechainChainId)}`,
211
+ conversion: `→ ${destinationToken.symbol}`,
212
+ fromToken: anchorNode,
213
+ toToken: destinationNode,
214
+ feeUsdValue: crossingFeeUsd,
215
+ // NOT automatic, and this is the difference the whole route turns on. On a
216
+ // one-signature route the aggregator's executor makes this call; here the
217
+ // reader does, by hand, after the anchor lands.
218
+ automatic: false,
219
+ };
220
+ const crossingSection = {
221
+ id: `${candidate.id}-signature-2`,
222
+ label: `Bridge to ${(0, chain_names_js_1.chainDisplayName)(producers_js_1.pulsechainChainId)}`,
223
+ providerKey: omnibridgeProviderKey,
224
+ tokenFlow: [anchorNode, destinationNode],
225
+ landing: {
226
+ amount: candidate.deliveredAmount,
227
+ decimals: destinationToken.decimals,
228
+ symbol: destinationToken.symbol,
229
+ usdValue: (0, producers_js_1.subtractUsdValues)(landedUsd, crossingFeeUsd),
230
+ },
231
+ feeUsdValue: crossingFeeUsd,
232
+ // THE FLAG THAT MAKES THE ROUTE HONEST. It is what draws "You sign this
233
+ // later" on the step, what makes the primary button name the step it
234
+ // actually signs, and what stops any surface stating the delivered amount
235
+ // as settled. Removing it would turn this into a route that silently
236
+ // promises one signature and asks for two.
237
+ deferred: true,
238
+ // `sectionDescription` in the route strip reads `section.deferredNote ??
239
+ // defaultDeferredNote()`, so a note supplied HERE replaces the default
240
+ // sentence outright rather than adding to it. The default sentence is
241
+ // "Fee is approximate — quoted when you return." — the one fact that
242
+ // tells the reader the output figure they are looking at is not settled.
243
+ // A note that names only the second signature and drops that fact leaves
244
+ // a settled-looking figure on screen with nothing anywhere saying
245
+ // otherwise, so this note must carry BOTH facts itself.
246
+ deferredNote: `The bridge crossing is a second signature you make once the funds arrive on ${(0, chain_names_js_1.chainDisplayName)(candidate.entryChainId)}. The amount shown is approximate and is quoted again when you return.`,
247
+ // The crossing's own settlement wait, which is the long part of the journey
248
+ // and has nothing to do with the aggregator's estimate above.
249
+ etaMinutes: producers_js_1.BRIDGE_SETTLEMENT_ETA_MINUTES,
250
+ hops: [crossingHop],
251
+ };
252
+ const totalCostUsdValue = aggregatorFeeUsd === null && crossingFeeUsd === null
253
+ ? null
254
+ : (aggregatorFeeUsd ?? 0) + (crossingFeeUsd ?? 0);
255
+ return {
256
+ kind: 'aggregated',
257
+ entryChainId: candidate.entryChainId,
258
+ // Named after the omnibridge, matching the one-signature route: a route is
259
+ // named for the thing that performs its defining leg.
260
+ headlineProviderKey: omnibridgeProviderKey,
261
+ sections: [aggregatorSection, crossingSection],
262
+ output: {
263
+ amount: candidate.deliveredAmount,
264
+ decimals: destinationToken.decimals,
265
+ symbol: destinationToken.symbol,
266
+ // The source basis, carried the whole way: what was paid, less what each
267
+ // leg costs. Re-pricing the delivered token against its own feed would
268
+ // state this route's cost twice and the two would not agree.
269
+ usdValue: (0, producers_js_1.subtractUsdValues)(paidUsd, totalCostUsdValue),
270
+ },
271
+ totalCostUsdValue,
272
+ // Ranked on the same net figure as every other route: delivered value less
273
+ // everything the journey costs.
274
+ netValueUsd: (0, producers_js_1.subtractUsdValues)(paidUsd, totalCostUsdValue),
275
+ // The reader's wait is BOTH legs, not the aggregator's leg alone. A route
276
+ // that reported only the first would claim to finish before its second
277
+ // signature had even been asked for.
278
+ etaMinutes: (etaMinutes ?? 0) + producers_js_1.BRIDGE_SETTLEMENT_ETA_MINUTES,
279
+ };
280
+ };
281
+ exports.buildNearIntentsTwoStepRouteData = buildNearIntentsTwoStepRouteData;
282
+ /**
283
+ * Describes the anchor a two-signature route leaves the reader holding.
284
+ *
285
+ * A small constructor rather than an inline object literal at the call site,
286
+ * so the three fields are named and documented in one place and a caller
287
+ * cannot quietly pair one aggregator's amount with another's valuation.
288
+ *
289
+ * @param options.anchorToken - the entry-chain token the aggregator delivers
290
+ * @param options.anchorAmount - how much of it lands, in its base units
291
+ * @param options.anchorUsdValue - the AGGREGATOR'S own valuation of that landing
292
+ * @returns the deferred-crossing record, or null when no amount is known
293
+ */
294
+ const describeDeferredCrossing = ({ anchorToken, anchorAmount, anchorUsdValue, }) => {
295
+ if (anchorToken === null) {
296
+ return null;
297
+ }
298
+ if (anchorAmount === null || anchorAmount === undefined || anchorAmount <= 0n) {
299
+ return null;
300
+ }
301
+ return { anchorToken, anchorAmount, anchorUsdValue: anchorUsdValue ?? null };
302
+ };
303
+ exports.describeDeferredCrossing = describeDeferredCrossing;