@gibs/bridge-sdk 1.12.0 → 1.13.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 (117) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +234 -432
  3. package/dist/abis.d.ts +1 -0
  4. package/dist/bridge-limits.d.ts +103 -0
  5. package/dist/bridge-limits.js +84 -0
  6. package/dist/chain-info.d.ts +169 -0
  7. package/dist/chain-info.js +410 -0
  8. package/dist/chain-names.d.ts +160 -0
  9. package/dist/chain-names.js +200 -0
  10. package/dist/chains.d.ts +65 -0
  11. package/dist/chains.js +284 -0
  12. package/dist/config.d.ts +216 -0
  13. package/dist/config.js +493 -0
  14. package/dist/consolidated-quote.d.ts +554 -0
  15. package/dist/consolidated-quote.js +773 -0
  16. package/dist/destination-calldata.d.ts +118 -0
  17. package/dist/destination-calldata.js +152 -0
  18. package/dist/ecosystems.d.ts +217 -0
  19. package/dist/ecosystems.js +288 -0
  20. package/dist/fee-type.d.ts +10 -0
  21. package/dist/fee-type.js +9 -0
  22. package/dist/hyperliquid-execution.d.ts +152 -0
  23. package/dist/hyperliquid-execution.js +168 -0
  24. package/dist/image-links.d.ts +117 -0
  25. package/dist/image-links.js +142 -0
  26. package/dist/index.d.ts +20 -0
  27. package/dist/index.js +20 -0
  28. package/dist/lifi-execution-guard.d.ts +199 -0
  29. package/dist/lifi-execution-guard.js +400 -0
  30. package/dist/near-intents-conformance.d.ts +85 -0
  31. package/dist/near-intents-conformance.js +329 -0
  32. package/dist/near-intents-route.d.ts +47 -0
  33. package/dist/near-intents-route.js +265 -0
  34. package/dist/near-intents.d.ts +524 -0
  35. package/dist/near-intents.js +1055 -0
  36. package/dist/origin-deposit.d.ts +326 -0
  37. package/dist/origin-deposit.js +68 -0
  38. package/dist/pre-quote.d.ts +198 -0
  39. package/dist/pre-quote.js +175 -0
  40. package/dist/prices.d.ts +107 -0
  41. package/dist/prices.js +162 -0
  42. package/dist/providers.d.ts +221 -0
  43. package/dist/providers.js +157 -0
  44. package/dist/quote-fees.d.ts +102 -0
  45. package/dist/quote-fees.js +195 -0
  46. package/dist/referral.d.ts +77 -0
  47. package/dist/referral.js +72 -0
  48. package/dist/relay-currencies.d.ts +47 -0
  49. package/dist/relay-currencies.js +89 -0
  50. package/dist/relay-quote.d.ts +301 -0
  51. package/dist/relay-quote.js +983 -0
  52. package/dist/route-steps.d.ts +138 -0
  53. package/dist/route-steps.js +305 -0
  54. package/dist/routing/amounts.d.ts +80 -0
  55. package/dist/routing/amounts.js +120 -0
  56. package/dist/routing/candidate-route.d.ts +43 -0
  57. package/dist/routing/candidate-route.js +45 -0
  58. package/dist/routing/candidate.d.ts +237 -0
  59. package/dist/routing/candidate.js +96 -0
  60. package/dist/routing/carriers/ask-answer.d.ts +58 -0
  61. package/dist/routing/carriers/ask-answer.js +1 -0
  62. package/dist/routing/carriers/omnibridge.d.ts +137 -0
  63. package/dist/routing/carriers/omnibridge.js +419 -0
  64. package/dist/routing/carriers/pulsex.d.ts +111 -0
  65. package/dist/routing/carriers/pulsex.js +404 -0
  66. package/dist/routing/carriers/wrap.d.ts +25 -0
  67. package/dist/routing/carriers/wrap.js +115 -0
  68. package/dist/routing/composed-route-quality.d.ts +103 -0
  69. package/dist/routing/composed-route-quality.js +108 -0
  70. package/dist/routing/entry-chain-anchor.d.ts +88 -0
  71. package/dist/routing/entry-chain-anchor.js +55 -0
  72. package/dist/routing/format.d.ts +31 -0
  73. package/dist/routing/format.js +58 -0
  74. package/dist/routing/index.d.ts +34 -0
  75. package/dist/routing/index.js +42 -0
  76. package/dist/routing/producers.d.ts +770 -0
  77. package/dist/routing/producers.js +1564 -0
  78. package/dist/routing/providers.d.ts +26 -0
  79. package/dist/routing/providers.js +38 -0
  80. package/dist/routing/route-data.d.ts +355 -0
  81. package/dist/routing/route-data.js +1 -0
  82. package/dist/routing/search/compose.d.ts +168 -0
  83. package/dist/routing/search/compose.js +98 -0
  84. package/dist/routing/search/graph.d.ts +639 -0
  85. package/dist/routing/search/graph.js +445 -0
  86. package/dist/routing/search/plan-route-data.d.ts +244 -0
  87. package/dist/routing/search/plan-route-data.js +767 -0
  88. package/dist/routing/search/score.d.ts +324 -0
  89. package/dist/routing/search/score.js +400 -0
  90. package/dist/routing/usd-value.d.ts +17 -0
  91. package/dist/routing/usd-value.js +25 -0
  92. package/dist/settings.d.ts +692 -0
  93. package/dist/settings.js +909 -0
  94. package/dist/ton-execution.d.ts +117 -0
  95. package/dist/ton-execution.js +247 -0
  96. package/dist/tron-execution.d.ts +146 -0
  97. package/dist/tron-execution.js +239 -0
  98. package/dist/types.d.ts +51 -0
  99. package/dist/types.js +1 -0
  100. package/package.json +203 -23
  101. package/src/chain-info.test.ts +0 -968
  102. package/src/chain-info.ts +0 -498
  103. package/src/chains.test.ts +0 -123
  104. package/src/chains.ts +0 -88
  105. package/src/config.test.ts +0 -679
  106. package/src/config.ts +0 -500
  107. package/src/fee-type.test.ts +0 -45
  108. package/src/fee-type.ts +0 -14
  109. package/src/image-links.test.ts +0 -160
  110. package/src/image-links.ts +0 -65
  111. package/src/index.ts +0 -8
  112. package/src/settings.test.ts +0 -2754
  113. package/src/settings.ts +0 -875
  114. package/src/types.ts +0 -48
  115. package/tsconfig.json +0 -17
  116. package/vitest.config.ts +0 -13
  117. /package/{src/abis.ts → dist/abis.js} +0 -0
@@ -0,0 +1,326 @@
1
+ import type { Hex } from 'viem';
2
+ /**
3
+ * An Ethereum-Virtual-Machine origin deposit: the transaction the user signs on
4
+ * the source chain.
5
+ *
6
+ * Every variant in {@link OriginDeposit} is produced by the Relay parser, but
7
+ * being produced is not the same as being signable: a variant can only be
8
+ * executed where the interface has a wallet adapter for its ecosystem. This
9
+ * repository's interface now has one for every variant below, including Tron and
10
+ * The Open Network. An interface that does not must reject the variant
11
+ * explicitly rather than let it reach a signer meant for another ecosystem.
12
+ */
13
+ export type EvmDeposit = {
14
+ ecosystem: 'evm';
15
+ to: Hex;
16
+ data: Hex;
17
+ value: bigint;
18
+ chainId: number;
19
+ gasLimit: bigint | null;
20
+ };
21
+ /** One Solana instruction: the account metas, the program, and hex-encoded instruction data. */
22
+ export type SolanaInstruction = {
23
+ keys: Array<{
24
+ pubkey: string;
25
+ isSigner: boolean;
26
+ isWritable: boolean;
27
+ }>;
28
+ programId: string;
29
+ data: string;
30
+ };
31
+ /**
32
+ * A Solana origin deposit expressed as the raw instruction set plus the
33
+ * address-lookup-table addresses, which the execution layer compiles into a
34
+ * versioned transaction with the Solana web3 library. There is no separate
35
+ * fee-payer field — the fee payer is the signer account inside an
36
+ * instruction's keys. This is the shape Relay returns.
37
+ *
38
+ * Because the transaction is compiled at signing time, its recent blockhash is
39
+ * stamped then too, so this form does not go stale while the user deliberates.
40
+ */
41
+ export type SolanaInstructionsDeposit = {
42
+ ecosystem: 'svm';
43
+ form: 'instructions';
44
+ instructions: SolanaInstruction[];
45
+ addressLookupTableAddresses: string[];
46
+ chainId: number;
47
+ };
48
+ /**
49
+ * A Solana origin deposit that arrives ALREADY COMPILED: a base64 versioned
50
+ * (v0) transaction the wallet deserializes, signs and sends unchanged. This is
51
+ * the shape LI.FI's plain `/v1/quote` returns for a Solana origin, where the
52
+ * whole payload is a single `transactionRequest.data` string with no `to`,
53
+ * `value` or `chainId` beside it.
54
+ *
55
+ * The two forms are kept as separate members of a discriminated union rather
56
+ * than one type with optional fields, because they are not interchangeable at
57
+ * the signer: this one must NOT be recompiled or re-stamped, and the
58
+ * instruction form cannot be signed without being compiled first.
59
+ *
60
+ * GOTCHA: the quote bakes a recent blockhash into the serialized bytes, so this
61
+ * form EXPIRES (Solana retains roughly 150 blocks, on the order of a minute).
62
+ * A quote the user sits on will be rejected as an expired blockhash rather than
63
+ * silently re-priced, so treat a stale-transaction failure as "re-quote", not
64
+ * as a wallet fault.
65
+ */
66
+ export type SolanaSerializedDeposit = {
67
+ ecosystem: 'svm';
68
+ form: 'serialized';
69
+ /** The compiled v0 transaction, base64, exactly as the provider returned it. */
70
+ transaction: string;
71
+ chainId: number;
72
+ };
73
+ /** A Solana origin deposit in either of the two forms providers return. */
74
+ export type SolanaDeposit = SolanaInstructionsDeposit | SolanaSerializedDeposit;
75
+ /** A Bitcoin origin deposit: either a partially-signed transaction, or a deposit address plus an amount in satoshis. */
76
+ export type BitcoinDeposit = {
77
+ ecosystem: 'bvm';
78
+ psbt: string | null;
79
+ depositAddress: string;
80
+ amountSats: bigint;
81
+ chainId: number;
82
+ };
83
+ /**
84
+ * A Tron origin deposit: one contract call for the user's wallet to sign and
85
+ * broadcast. Relay returns Tron's own wire shape, whose field names are
86
+ * snake_case and whose addresses are hex with Tron's `41` prefix byte rather
87
+ * than `0x`; the fields are renamed here to the codebase's conventions and the
88
+ * wire name of each is recorded so a signer can map back without guessing.
89
+ */
90
+ export type TronDeposit = {
91
+ ecosystem: 'tvm';
92
+ /** Tron contract type; `TriggerSmartContract` is the only shape Relay returns. Wire name `type`. */
93
+ contractType: string;
94
+ /** The signer's account, hex with Tron's `41` prefix. Wire name `parameter.owner_address`. */
95
+ ownerAddress: string;
96
+ /** The contract being called, hex with Tron's `41` prefix. Wire name `parameter.contract_address`. */
97
+ contractAddress: string;
98
+ /** Native TRX sent with the call, in sun. Wire name `parameter.call_value`. */
99
+ callValue: bigint;
100
+ /** Call data as bare hex with NO `0x` prefix, unlike every Ethereum payload. Wire name `parameter.data`. */
101
+ data: string;
102
+ chainId: number;
103
+ };
104
+ /**
105
+ * One message in a TON deposit. TON wallets send a list of messages rather than
106
+ * a single transaction, and the payload (`body`) is a base64 bag-of-cells, not
107
+ * hex.
108
+ */
109
+ export type TonMessage = {
110
+ /** Destination account. */
111
+ to: string;
112
+ /** Amount attached to the message, in nanotons. */
113
+ value: bigint;
114
+ /** Base64 bag-of-cells payload. */
115
+ body: string;
116
+ /** TON send mode flags. */
117
+ mode: number;
118
+ /** Whether the message bounces back if the destination cannot accept it. */
119
+ bounce: boolean;
120
+ /** Sending account; absent when the wallet is left to fill it in. */
121
+ from: string | null;
122
+ };
123
+ /**
124
+ * A TON origin deposit: the message list the user's wallet signs and sends.
125
+ */
126
+ export type TonDeposit = {
127
+ ecosystem: 'tonvm';
128
+ messages: TonMessage[];
129
+ chainId: number;
130
+ };
131
+ /** One field of an typed-data structure: its name and its solidity-style type. */
132
+ export type TypedDataField = {
133
+ name: string;
134
+ type: string;
135
+ };
136
+ /**
137
+ * The authorization a Hyperliquid deposit must complete BEFORE its action is
138
+ * submitted: the user signs `sign` as typed data, then the signature and `post`
139
+ * are sent to Relay. Skipping it makes the action unusable, which is why it
140
+ * travels with the deposit rather than being dropped as a separate step.
141
+ */
142
+ export type HyperliquidAuthorization = {
143
+ /** The typed-data structure the user signs. */
144
+ sign: {
145
+ /** Signing scheme; `eip712` is the only value observed. */
146
+ signatureKind: string;
147
+ domain: Record<string, unknown>;
148
+ types: Record<string, TypedDataField[]>;
149
+ value: Record<string, unknown>;
150
+ primaryType: string;
151
+ };
152
+ /** Where the resulting signature is submitted. */
153
+ post: {
154
+ endpoint: string;
155
+ method: string;
156
+ body: Record<string, unknown>;
157
+ };
158
+ };
159
+ /**
160
+ * A Hyperliquid origin deposit. Unlike every other ecosystem, nothing here is
161
+ * broadcast to a chain: the user signs a typed-data ACTION and it is posted to
162
+ * Hyperliquid's API. There is therefore no transaction, no gas, and no calldata
163
+ * — and two signatures are required, the {@link HyperliquidAuthorization} first
164
+ * and this action second.
165
+ */
166
+ export type HyperliquidDeposit = {
167
+ ecosystem: 'hypevm';
168
+ /** The action to sign, e.g. `sendAsset`, with its parameters. */
169
+ action: {
170
+ type: string;
171
+ parameters: Record<string, unknown>;
172
+ };
173
+ /** Typed-data structures for the action. */
174
+ eip712Types: Record<string, TypedDataField[]>;
175
+ /** Which structure in `eip712Types` the action signs. */
176
+ eip712PrimaryType: string;
177
+ /** Replay-protection nonce, shared with the authorization. */
178
+ nonce: bigint;
179
+ /** The authorization to complete first; null when Relay omits that step. */
180
+ authorization: HyperliquidAuthorization | null;
181
+ chainId: number;
182
+ };
183
+ /**
184
+ * An origin deposit that is an ADDRESS AND AN AMOUNT, with no transaction of
185
+ * any kind — not a signed one, not an unsigned one, not a partially-signed one.
186
+ * The reader pays it by hand, from any wallet or any exchange, on a chain this
187
+ * interface has no wallet connector for.
188
+ *
189
+ * DISCRIMINATED BY `kind`, NOT BY `ecosystem`, AND THAT IS DELIBERATE. Every
190
+ * other variant here is tagged with the ecosystem whose signer it needs. This
191
+ * one needs no signer, and the SAME shape serves Zcash, Dogecoin, Litecoin and the
192
+ * XRP Ledger alike — the chain is `chainId`, not the type. Tagging it with an
193
+ * ecosystem would force one variant per chain for no difference in handling,
194
+ * and would let an ecosystem guard such as {@link isBitcoinDeposit} claim a
195
+ * deposit that has nothing to sign.
196
+ *
197
+ * NOT A VARIANT OF {@link BitcoinDeposit}, AND THE DIFFERENCE IS THE POINT.
198
+ * `BitcoinDeposit.psbt` is nullable, so it can already carry an address and no
199
+ * partially-signed transaction. But a name is a claim: `psbt` says a
200
+ * partially-signed Bitcoin transaction is the thing that might be missing, and
201
+ * here there is no such thing even in principle. A reader who found
202
+ * `psbt: null` on a Zcash deposit would reach for the signer that fills it in.
203
+ * There is no signer.
204
+ *
205
+ * WHERE EVERY FIELD COMES FROM, because this is the whole safety argument: the
206
+ * address is read off the provider's LIVE answer and nowhere else. It is never
207
+ * typed, never seeded from a link, never derived on this side. A provider
208
+ * answer with no address produces no deposit, and therefore no screen.
209
+ *
210
+ * HOW IT MOVES FORWARD. Nothing here is signed or broadcast. The reader sends
211
+ * an ordinary transfer, the provider's own watcher sees it arrive at the
212
+ * address it issued, and the existing status poll — keyed by this same
213
+ * address — reports the fill.
214
+ */
215
+ export type DepositAddressDeposit = {
216
+ kind: 'deposit-address';
217
+ /** The origin chain. */
218
+ chainId: number;
219
+ /**
220
+ * The address the provider reserved for this one quote, exactly as it
221
+ * answered. Single-use: a second quote for the same route gets a different
222
+ * address.
223
+ */
224
+ depositAddress: string;
225
+ /**
226
+ * What the reader is asked to send, in base units of the origin asset. The
227
+ * amount the quote was priced at.
228
+ */
229
+ amount: bigint;
230
+ /**
231
+ * The smallest payment the provider will still fill, in the same base units.
232
+ *
233
+ * NOT A RESTATEMENT OF `amount`. The request asks for a flexible input, so
234
+ * the provider names a floor about one percent under the quote and fills
235
+ * anything at or above it. A reader typing a figure into an exchange
236
+ * withdrawal form misses the exact amount routinely, and this tolerance is
237
+ * what turns those payments into fills rather than refunds.
238
+ */
239
+ minimumAmount: bigint;
240
+ /** Decimal places of the origin asset, so a screen can print the amounts without a second lookup. */
241
+ decimals: number;
242
+ /**
243
+ * When the address goes cold, in milliseconds since the epoch.
244
+ *
245
+ * READ OFF THE ANSWER, NEVER OFF THE ECHOED REQUEST. The provider discards
246
+ * the deadline a caller asks for and substitutes one three days out. A screen
247
+ * built on the echoed request would run a thirty-minute countdown against an
248
+ * address that is live for three days.
249
+ */
250
+ expiresAtMs: number;
251
+ };
252
+ /**
253
+ * A route that has been PRICED BUT NOT RESERVED: there is nothing to pay yet.
254
+ *
255
+ * WHY IT EXISTS. NEAR Intents reserves a real deposit address, with a
256
+ * three-day clock, for every live quote it answers. Asking live merely to draw
257
+ * a route on screen reserved one per keystroke, per route, for readers who
258
+ * mostly never paid, and registered their recipient and refund accounts with
259
+ * the provider on every glance. So a route on display is priced with a dry
260
+ * quote, which carries figures and no address, and its deposit says so here.
261
+ *
262
+ * WHAT A SURFACE MUST DO WITH ONE. Nothing that pays: it has no address, no
263
+ * calldata and no amount to send. The moment the reader commits — the press
264
+ * before a signature, or "Show payment address" on a route paid by hand — the
265
+ * surface asks for a live quote and pays that one instead, having checked its
266
+ * terms against what the reader was shown.
267
+ */
268
+ export type UnreservedDeposit = {
269
+ kind: 'unreserved';
270
+ /** The origin chain the route was priced from. */
271
+ chainId: number;
272
+ };
273
+ /** The origin deposit for any supported source ecosystem. */
274
+ export type OriginDeposit = EvmDeposit | SolanaDeposit | BitcoinDeposit | TronDeposit | TonDeposit | HyperliquidDeposit | DepositAddressDeposit | UnreservedDeposit;
275
+ export declare const isEvmDeposit: (deposit: OriginDeposit) => deposit is EvmDeposit;
276
+ export declare const isSolanaDeposit: (deposit: OriginDeposit) => deposit is SolanaDeposit;
277
+ /**
278
+ * Narrows a Solana deposit to the instruction form, which must be compiled
279
+ * before it can be signed.
280
+ */
281
+ export declare const isSolanaInstructionsDeposit: (deposit: SolanaDeposit) => deposit is SolanaInstructionsDeposit;
282
+ /**
283
+ * Narrows a Solana deposit to the pre-compiled form, which must be signed
284
+ * as-is.
285
+ */
286
+ export declare const isSolanaSerializedDeposit: (deposit: SolanaDeposit) => deposit is SolanaSerializedDeposit;
287
+ export declare const isBitcoinDeposit: (deposit: OriginDeposit) => deposit is BitcoinDeposit;
288
+ export declare const isTronDeposit: (deposit: OriginDeposit) => deposit is TronDeposit;
289
+ export declare const isTonDeposit: (deposit: OriginDeposit) => deposit is TonDeposit;
290
+ export declare const isHyperliquidDeposit: (deposit: OriginDeposit) => deposit is HyperliquidDeposit;
291
+ /**
292
+ * Narrows a deposit to the pay-by-hand shape: an address, an amount, and
293
+ * nothing to sign.
294
+ *
295
+ * THE GUARD EVERY EXECUTION PATH MUST ASK FIRST. A surface that falls through
296
+ * to a signer with one of these has no transaction to give it, and a surface
297
+ * that asks the reader to connect a wallet is asking for one that does not
298
+ * exist for this chain.
299
+ *
300
+ * @param deposit - any origin deposit
301
+ * @returns whether the reader pays this one by hand
302
+ */
303
+ export declare const isDepositAddressDeposit: (deposit: OriginDeposit) => deposit is DepositAddressDeposit;
304
+ /**
305
+ * Narrows a deposit to the priced-but-not-reserved shape: a route on display,
306
+ * with nothing to pay until a live quote replaces it.
307
+ *
308
+ * @param deposit - any origin deposit
309
+ * @returns whether the route must be quoted live before anything is paid
310
+ */
311
+ export declare const isUnreservedDeposit: (deposit: OriginDeposit) => deposit is UnreservedDeposit;
312
+ /**
313
+ * Names a deposit's family for a message shown to someone: its ecosystem, or
314
+ * its `kind` for a deposit that has none — a {@link DepositAddressDeposit}
315
+ * reads as `"deposit-address"`, an {@link UnreservedDeposit} as `"unreserved"`.
316
+ *
317
+ * THE ONE COPY. The same `'ecosystem' in deposit ? deposit.ecosystem :
318
+ * deposit.kind` expression used to be written out separately in
319
+ * `consolidated-quote.ts` and in the interface's `consolidated-execute.ts`;
320
+ * each copy was a chance for the two to describe the same deposit
321
+ * differently. Import this instead of restating the expression.
322
+ *
323
+ * @param deposit - any origin deposit
324
+ * @returns the ecosystem name, or the deposit's `kind` when it has none
325
+ */
326
+ export declare const depositFamilyOf: (deposit: OriginDeposit) => string;
@@ -0,0 +1,68 @@
1
+ /**
2
+ * The ecosystem whose signer a deposit needs, or null for a deposit that needs
3
+ * no signer at all.
4
+ *
5
+ * THE ONE PLACE THE ECOSYSTEM TAG IS READ. A {@link DepositAddressDeposit} has
6
+ * no `ecosystem`, so every guard below asks through this instead of reading the
7
+ * field directly — which also means no ecosystem guard can ever answer true for
8
+ * a deposit the reader pays by hand.
9
+ *
10
+ * TYPED `Ecosystem | null`, NOT `string | null`. A `string` return let a typo
11
+ * such as `signerEcosystemOf(deposit) === 'hypvm'` compile silently — the
12
+ * comparison is just false forever, so `isHyperliquidDeposit` would always
13
+ * answer false and every Hyperliquid deposit would fall through to the
14
+ * Ethereum branch. Typed on the union, the same typo fails to compile instead.
15
+ */
16
+ const signerEcosystemOf = (deposit) => 'ecosystem' in deposit ? deposit.ecosystem : null;
17
+ export const isEvmDeposit = (deposit) => signerEcosystemOf(deposit) === 'evm';
18
+ export const isSolanaDeposit = (deposit) => signerEcosystemOf(deposit) === 'svm';
19
+ /**
20
+ * Narrows a Solana deposit to the instruction form, which must be compiled
21
+ * before it can be signed.
22
+ */
23
+ export const isSolanaInstructionsDeposit = (deposit) => deposit.form === 'instructions';
24
+ /**
25
+ * Narrows a Solana deposit to the pre-compiled form, which must be signed
26
+ * as-is.
27
+ */
28
+ export const isSolanaSerializedDeposit = (deposit) => deposit.form === 'serialized';
29
+ export const isBitcoinDeposit = (deposit) => signerEcosystemOf(deposit) === 'bvm';
30
+ export const isTronDeposit = (deposit) => signerEcosystemOf(deposit) === 'tvm';
31
+ export const isTonDeposit = (deposit) => signerEcosystemOf(deposit) === 'tonvm';
32
+ export const isHyperliquidDeposit = (deposit) => signerEcosystemOf(deposit) === 'hypevm';
33
+ /**
34
+ * Narrows a deposit to the pay-by-hand shape: an address, an amount, and
35
+ * nothing to sign.
36
+ *
37
+ * THE GUARD EVERY EXECUTION PATH MUST ASK FIRST. A surface that falls through
38
+ * to a signer with one of these has no transaction to give it, and a surface
39
+ * that asks the reader to connect a wallet is asking for one that does not
40
+ * exist for this chain.
41
+ *
42
+ * @param deposit - any origin deposit
43
+ * @returns whether the reader pays this one by hand
44
+ */
45
+ export const isDepositAddressDeposit = (deposit) => 'kind' in deposit && deposit.kind === 'deposit-address';
46
+ /**
47
+ * Narrows a deposit to the priced-but-not-reserved shape: a route on display,
48
+ * with nothing to pay until a live quote replaces it.
49
+ *
50
+ * @param deposit - any origin deposit
51
+ * @returns whether the route must be quoted live before anything is paid
52
+ */
53
+ export const isUnreservedDeposit = (deposit) => 'kind' in deposit && deposit.kind === 'unreserved';
54
+ /**
55
+ * Names a deposit's family for a message shown to someone: its ecosystem, or
56
+ * its `kind` for a deposit that has none — a {@link DepositAddressDeposit}
57
+ * reads as `"deposit-address"`, an {@link UnreservedDeposit} as `"unreserved"`.
58
+ *
59
+ * THE ONE COPY. The same `'ecosystem' in deposit ? deposit.ecosystem :
60
+ * deposit.kind` expression used to be written out separately in
61
+ * `consolidated-quote.ts` and in the interface's `consolidated-execute.ts`;
62
+ * each copy was a chance for the two to describe the same deposit
63
+ * differently. Import this instead of restating the expression.
64
+ *
65
+ * @param deposit - any origin deposit
66
+ * @returns the ecosystem name, or the deposit's `kind` when it has none
67
+ */
68
+ export const depositFamilyOf = (deposit) => 'ecosystem' in deposit ? deposit.ecosystem : deposit.kind;
@@ -0,0 +1,198 @@
1
+ import type { Hex } from 'viem';
2
+ import { type OriginVmType } from './consolidated-quote.js';
3
+ import { type RelayTradeType } from './relay-quote.js';
4
+ /**
5
+ * Phase one of the two-phase consolidated-route quoting model ("option 2").
6
+ *
7
+ * The consolidated route swaps the user's origin token into an ANCHOR token on
8
+ * an omnibridge entry chain (Ethereum or Binance Smart Chain), then the
9
+ * omnibridge crosses that anchor onto PulseChain. The execution quote
10
+ * (consolidated-quote / relay-quote) is EXACT_OUTPUT: it solves BACKWARD to a
11
+ * FIXED anchor amount, because the omnibridge entry call encodes that exact
12
+ * amount and it must arrive exactly.
13
+ *
14
+ * The problem the EXACT_OUTPUT path cannot answer on its own is "for the user's
15
+ * fixed input, how much anchor does this entry actually deliver?". Previously
16
+ * that target was estimated from PRICES, which is fragile (garbage when a price
17
+ * is missing) and makes every entry target the same value-equivalent amount, so
18
+ * the routes deliver alike and cannot be ranked by who delivers most.
19
+ *
20
+ * The PRE-QUOTE solves that: a plain EXACT_INPUT swap of origin token -> anchor
21
+ * for the FIXED input, with NO destination transactions. Its delivered amount
22
+ * is provider-accurate and decimals-correct, with no price dependency. The
23
+ * caller feeds that delivered amount as the EXACT_OUTPUT `toAmount`, so each
24
+ * entry now targets its OWN real delivered amount and ranking-by-delivered
25
+ * becomes meaningful.
26
+ *
27
+ * These builders/parsers are deliberately SEPARATE from the EXACT_OUTPUT
28
+ * consolidated builders so the execution path is never disturbed.
29
+ */
30
+ /**
31
+ * Provider-agnostic input for an EXACT_INPUT origin -> anchor pre-quote. A plain
32
+ * swap: no destination calls, no recipient on PulseChain, no omnibridge entry
33
+ * call. Carries only what a forward-solving swap needs.
34
+ */
35
+ export type PreQuoteRequest = {
36
+ /** Chain the user's funds start on. */
37
+ fromChainId: number;
38
+ /**
39
+ * Origin token address. Typed `string` (not `Hex`) so a non-Ethereum native
40
+ * currency address (Solana base58 mint, Bitcoin native string) flows through
41
+ * unchanged; an Ethereum Virtual Machine address is a subset of `string`.
42
+ */
43
+ fromTokenAddress: string;
44
+ /**
45
+ * The user's origin-chain address. Typed `string` for the same reason as
46
+ * `fromTokenAddress`: a non-Ethereum origin carries a base58/bech32 address.
47
+ */
48
+ fromAddress: string;
49
+ /** The omnibridge entry chain whose anchor token is the swap target. */
50
+ toChainId: number;
51
+ /** The anchor token on the entry chain; always an Ethereum Virtual Machine address. */
52
+ toTokenAddress: Hex;
53
+ /** The user's FIXED input amount, in origin-token base units. */
54
+ amount: bigint;
55
+ /** Maximum slippage as a fraction (e.g. 0.005); provider default when omitted. */
56
+ slippage?: number;
57
+ /**
58
+ * Virtual-machine family of the ORIGIN chain. Defaults to Ethereum Virtual
59
+ * Machine when absent. A non-Ethereum origin (`svm`/`bvm`) excludes LI.FI (it
60
+ * cannot cross ecosystems) and routes the Relay refund to the user's own
61
+ * origin address.
62
+ */
63
+ originVmType?: OriginVmType;
64
+ /**
65
+ * Where the swapped anchor conceptually lands on the entry chain (an
66
+ * Ethereum Virtual Machine address). REQUIRED for a non-Ethereum origin:
67
+ * Relay validates this address's FORMAT against `toChainId` even though the
68
+ * pre-quote never executes (no `txs` are attached), so a non-Ethereum
69
+ * origin's own base58/bech32 `fromAddress` is rejected outright — it is not
70
+ * an Ethereum-format address. Omitted (and defaulted to `fromAddress`) for
71
+ * an Ethereum origin, preserving the pre-quote's original behavior there.
72
+ */
73
+ recipient?: Hex;
74
+ /**
75
+ * The `referrer` sent to Relay. Left out or `null`, the field is OMITTED —
76
+ * never sent as `''`. Relay's live behavior (verified 2026-09-23) answers a
77
+ * keyless request with NO `referrer` field 200, but treats ANY `referrer` —
78
+ * including `''` — as "a referrer was supplied", which requires an API key
79
+ * and gets 401 without one. A package default would therefore break every
80
+ * caller without a key, so there is none. A string is sent as-is; Gibs
81
+ * Finance's own value is `relayReferrer` from `relay-quote.ts`.
82
+ */
83
+ relayReferrer?: string | null;
84
+ /**
85
+ * Overrides the `integrator` sent to LI.FI: `undefined` defaults to
86
+ * {@link lifiIntegrator} (a free attribution label, `gibs.finance`),
87
+ * `null` OMITS the `integrator` query parameter entirely (it is optional
88
+ * per LI.FI's own `/v1/quote` schema — verified 2026-09-23 — an empty
89
+ * string is not "absent", it is a literal empty integrator), and a string
90
+ * is sent as-is.
91
+ */
92
+ lifiIntegrator?: string | null;
93
+ };
94
+ /**
95
+ * The two delivered anchor amounts a pre-quote yields.
96
+ *
97
+ * Both come from the provider's own forward solve for the fixed input, so they
98
+ * are decimals-correct and free of any price dependency.
99
+ */
100
+ export type PreQuoteResult = {
101
+ /** The EXPECTED delivered anchor amount, for display and ranking. */
102
+ expectedAmount: bigint;
103
+ /**
104
+ * The GUARANTEED delivered anchor amount after slippage. This is the
105
+ * conservative figure the caller uses as the EXACT_OUTPUT `toAmount`, so the
106
+ * fixed input can actually achieve the execution target.
107
+ */
108
+ minimumAmount: bigint;
109
+ };
110
+ /**
111
+ * Plain LI.FI swap quote endpoint (forward-solving), re-exported from
112
+ * `consolidated-quote.js` rather than redeclared here — both modules must
113
+ * agree on the same address, and a second literal would be free to drift from
114
+ * it.
115
+ */
116
+ export { lifiQuoteUrl, lifiRequestHeaders } from './consolidated-quote.js';
117
+ /**
118
+ * The JSON body for a Relay EXACT_INPUT swap pre-quote. Mirrors
119
+ * `RelayQuoteRequestBody` but carries NO `txs` (it is a plain swap) and adds a
120
+ * `recipient` because, without destination calls, Relay needs an explicit
121
+ * delivery address on the entry chain.
122
+ */
123
+ export type RelayPreQuoteRequestBody = {
124
+ user: string;
125
+ originChainId: number;
126
+ originCurrency: string;
127
+ destinationChainId: number;
128
+ destinationCurrency: Hex;
129
+ amount: string;
130
+ tradeType: RelayTradeType;
131
+ /** Where the swapped anchor lands on the entry chain (the user, for a pre-quote). */
132
+ recipient: string;
133
+ /** Origin-chain refund target; required for Relay to enable automatic refunds. */
134
+ refundTo: string;
135
+ /**
136
+ * OPTIONAL — omitted entirely (not `''`) for an unconfigured host. See
137
+ * {@link PreQuoteRequest.relayReferrer}'s doc for why `null` and `''` are
138
+ * two different requests to Relay.
139
+ */
140
+ referrer?: string;
141
+ /** Maximum slippage in basis points; omitted when the caller defers to Relay. */
142
+ slippageTolerance?: string;
143
+ };
144
+ /**
145
+ * Builds the Relay EXACT_INPUT swap pre-quote body for a fixed input. NO `txs`
146
+ * are attached: Relay solves FORWARD and reports the delivered anchor amount.
147
+ *
148
+ * `recipient` and `refundTo` name TWO DIFFERENT chains and must never be
149
+ * conflated. `refundTo` is always the user's OWN origin-chain address — Relay
150
+ * refunds a failed (or, here, never-run) swap on the origin chain, and an
151
+ * Ethereum fallback address could not receive one there. `recipient` names
152
+ * where the swap lands on the ENTRY chain (`toChainId`), which is always
153
+ * Ethereum Virtual Machine — for an Ethereum origin the user's own address
154
+ * already satisfies that and is the default; for a non-Ethereum origin
155
+ * (Solana base58, Bitcoin bech32, ...) it does NOT, and Relay's `/quote/v2`
156
+ * validates the recipient's FORMAT against `toChainId` even though this
157
+ * pre-quote never executes. Sending the origin account there — as an earlier
158
+ * version of this builder did, reasoning that an unexecuted quote's recipient
159
+ * is "informational" — gets Relay's `400 INVALID_ADDRESS` on every
160
+ * non-Ethereum-origin pre-quote, which starves `fetchBestEntryAnchorPreQuote`
161
+ * of its only capable provider and surfaces as "No route available" for the
162
+ * whole non-Ethereum-origin flow. `request.recipient` (an explicit
163
+ * Ethereum-format address the caller supplies) is therefore REQUIRED for a
164
+ * non-Ethereum origin; without it this returns null.
165
+ *
166
+ * @param request - the provider-agnostic pre-quote request
167
+ * @returns the request body, or null when the input amount is non-positive or
168
+ * a non-Ethereum origin has no explicit Ethereum-format `recipient`
169
+ */
170
+ export declare const buildRelayPreQuoteRequest: (request: PreQuoteRequest) => RelayPreQuoteRequestBody | null;
171
+ /**
172
+ * Builds the plain LI.FI swap pre-quote as a query string for `GET /v1/quote`.
173
+ * LI.FI's plain `/quote` is forward-solving by construction (`fromAmount` in,
174
+ * `estimate.toAmount` out), so no trade-type flag is needed.
175
+ *
176
+ * Returns null for a non-Ethereum origin (LI.FI cannot bridge across
177
+ * virtual-machine ecosystems) and for a non-positive input amount.
178
+ *
179
+ * @param request - the provider-agnostic pre-quote request
180
+ * @returns the URL query string (without a leading `?`), or null
181
+ */
182
+ export declare const buildLifiPreQuoteRequest: (request: PreQuoteRequest) => string | null;
183
+ /**
184
+ * Parses a Relay EXACT_INPUT pre-quote response. The delivered anchor figures
185
+ * live under `details.currencyOut`: `amount` (expected) and `minimumAmount`
186
+ * (guaranteed slippage floor). Verified live against `api.relay.link/quote/v2`.
187
+ *
188
+ * @returns the delivered amounts, or null when the payload shape is unexpected
189
+ */
190
+ export declare const parseRelayPreQuote: (payload: unknown) => PreQuoteResult | null;
191
+ /**
192
+ * Parses a plain LI.FI `/quote` response. The delivered anchor figures live
193
+ * under `estimate`: `toAmount` (expected) and `toAmountMin` (guaranteed minimum
194
+ * after slippage) — the same estimate shape the route-step normalizer reads.
195
+ *
196
+ * @returns the delivered amounts, or null when the payload shape is unexpected
197
+ */
198
+ export declare const parseLifiPreQuote: (payload: unknown) => PreQuoteResult | null;