@gibs/bridge-sdk 1.18.0 → 1.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -0
- package/dist/abis.js +0 -2
- package/dist/bridge-limits.js +0 -38
- package/dist/chain-info.js +0 -116
- package/dist/chain-names.js +0 -151
- package/dist/chains.js +0 -198
- package/dist/cjs/abis.js +0 -2
- package/dist/cjs/bridge-limits.js +0 -38
- package/dist/cjs/chain-info.js +0 -116
- package/dist/cjs/chain-names.js +0 -151
- package/dist/cjs/chains.js +0 -198
- package/dist/cjs/claims.js +0 -60
- package/dist/cjs/config.js +1 -208
- package/dist/cjs/consolidated-quote.js +2 -464
- package/dist/cjs/destination-calldata.js +0 -71
- package/dist/cjs/ecosystems.js +0 -183
- package/dist/cjs/execution.js +0 -92
- package/dist/cjs/fee-type.js +0 -1
- package/dist/cjs/hyperliquid-execution.js +0 -98
- package/dist/cjs/image-links.js +0 -108
- package/dist/cjs/lifi-execution-guard.js +65 -172
- package/dist/cjs/near-intents-conformance.js +0 -110
- package/dist/cjs/near-intents-route.d.ts +13 -0
- package/dist/cjs/near-intents-route.js +7 -140
- package/dist/cjs/near-intents.js +0 -562
- package/dist/cjs/origin-deposit.js +0 -56
- package/dist/cjs/pre-quote.js +0 -80
- package/dist/cjs/prices.js +0 -113
- package/dist/cjs/providers.js +0 -83
- package/dist/cjs/quote-fees.js +0 -80
- package/dist/cjs/referral.js +0 -75
- package/dist/cjs/relay-currencies.js +0 -31
- package/dist/cjs/relay-depository.js +52 -77
- package/dist/cjs/relay-quote.js +0 -394
- package/dist/cjs/route-steps.js +0 -100
- package/dist/cjs/routing/amounts.js +0 -83
- package/dist/cjs/routing/candidate-route.d.ts +46 -1
- package/dist/cjs/routing/candidate-route.js +12 -40
- package/dist/cjs/routing/candidate.js +0 -46
- package/dist/cjs/routing/carrier-provider-key.js +0 -27
- package/dist/cjs/routing/carriers/omnibridge.js +0 -120
- package/dist/cjs/routing/carriers/pulsex-paths.js +0 -57
- package/dist/cjs/routing/carriers/pulsex-split.js +0 -92
- package/dist/cjs/routing/carriers/pulsex.js +0 -279
- package/dist/cjs/routing/carriers/wrap.js +0 -57
- package/dist/cjs/routing/composed-route-quality.js +0 -95
- package/dist/cjs/routing/entry-chain-anchor.js +0 -27
- package/dist/cjs/routing/format.js +0 -50
- package/dist/cjs/routing/index.d.ts +1 -1
- package/dist/cjs/routing/index.js +3 -30
- package/dist/cjs/routing/producers.js +0 -854
- package/dist/cjs/routing/providers.js +0 -27
- package/dist/cjs/routing/search/compose.js +0 -56
- package/dist/cjs/routing/search/graph.js +0 -364
- package/dist/cjs/routing/search/plan-route-data.js +5 -510
- package/dist/cjs/routing/search/score.js +0 -344
- package/dist/cjs/routing/swap-transactions.js +0 -74
- package/dist/cjs/routing/usd-value.js +0 -12
- package/dist/cjs/settings.js +1 -456
- package/dist/cjs/swap-venues.js +0 -17
- package/dist/cjs/ton-connect.js +0 -82
- package/dist/cjs/ton-execution.js +0 -6
- package/dist/cjs/ton.js +0 -42
- package/dist/cjs/tron-execution.js +0 -145
- package/dist/cjs/types.d.ts +8 -0
- package/dist/claims.js +0 -60
- package/dist/config.js +1 -211
- package/dist/consolidated-quote.js +2 -464
- package/dist/destination-calldata.js +0 -71
- package/dist/ecosystems.js +0 -183
- package/dist/execution.js +0 -92
- package/dist/fee-type.js +0 -2
- package/dist/hyperliquid-execution.js +0 -98
- package/dist/image-links.js +0 -108
- package/dist/lifi-execution-guard.js +65 -172
- package/dist/near-intents-conformance.js +0 -110
- package/dist/near-intents-route.d.ts +13 -0
- package/dist/near-intents-route.js +5 -139
- package/dist/near-intents.js +0 -562
- package/dist/origin-deposit.js +0 -56
- package/dist/pre-quote.js +0 -80
- package/dist/prices.js +0 -113
- package/dist/providers.js +0 -83
- package/dist/quote-fees.js +0 -80
- package/dist/referral.js +0 -75
- package/dist/relay-currencies.js +0 -31
- package/dist/relay-depository.js +52 -77
- package/dist/relay-quote.js +0 -394
- package/dist/route-steps.js +0 -100
- package/dist/routing/amounts.js +0 -83
- package/dist/routing/candidate-route.d.ts +46 -1
- package/dist/routing/candidate-route.js +10 -39
- package/dist/routing/candidate.js +0 -46
- package/dist/routing/carrier-provider-key.js +0 -27
- package/dist/routing/carriers/omnibridge.js +0 -120
- package/dist/routing/carriers/pulsex-paths.js +0 -57
- package/dist/routing/carriers/pulsex-split.js +0 -92
- package/dist/routing/carriers/pulsex.js +0 -279
- package/dist/routing/carriers/wrap.js +0 -57
- package/dist/routing/composed-route-quality.js +0 -95
- package/dist/routing/entry-chain-anchor.js +0 -27
- package/dist/routing/format.js +0 -50
- package/dist/routing/index.d.ts +1 -1
- package/dist/routing/index.js +1 -29
- package/dist/routing/producers.js +0 -854
- package/dist/routing/providers.js +0 -27
- package/dist/routing/search/compose.js +0 -56
- package/dist/routing/search/graph.js +0 -364
- package/dist/routing/search/plan-route-data.js +6 -511
- package/dist/routing/search/score.js +0 -344
- package/dist/routing/swap-transactions.js +0 -74
- package/dist/routing/usd-value.js +0 -12
- package/dist/settings.js +1 -456
- package/dist/swap-venues.js +0 -17
- package/dist/ton-connect.js +0 -82
- package/dist/ton-execution.js +0 -6
- package/dist/ton.js +0 -42
- package/dist/tron-execution.js +0 -145
- package/dist/types.d.ts +8 -0
- package/package.json +3 -3
package/dist/cjs/relay-quote.js
CHANGED
|
@@ -9,64 +9,9 @@ const referral_js_1 = require("./referral.js");
|
|
|
9
9
|
const chain_names_js_1 = require("./chain-names.js");
|
|
10
10
|
const route_steps_js_1 = require("./route-steps.js");
|
|
11
11
|
const quote_fees_js_1 = require("./quote-fees.js");
|
|
12
|
-
/**
|
|
13
|
-
* Relay (relay.link) as a second consolidated-route quote provider, competing
|
|
14
|
-
* with LI.FI on price. Relay quotes the same backwards-from-destination route:
|
|
15
|
-
* deliver exactly `toAmount` of the Ethereum-side token, then run our omnibridge
|
|
16
|
-
* entry call against it.
|
|
17
|
-
*
|
|
18
|
-
* One semantic differs from LI.FI and the difference is load-bearing. Relay has
|
|
19
|
-
* NO destination-chain fallback address. When the destination call cannot fill,
|
|
20
|
-
* Relay refunds on the ORIGIN chain to `refundTo`, in the origin currency — the
|
|
21
|
-
* user ends up back where they started, not holding the Ethereum-side token at
|
|
22
|
-
* a fallback. We therefore map our `fallbackAddress` onto `refundTo`; a failed
|
|
23
|
-
* Relay route is recovered on the origin chain, never stranded on Ethereum.
|
|
24
|
-
*/
|
|
25
|
-
/**
|
|
26
|
-
* Relay's API root. Steps carry RELATIVE post endpoints (`/authorize`), so a
|
|
27
|
-
* caller completing one has to resolve it against this.
|
|
28
|
-
*/
|
|
29
12
|
exports.relayApiBaseUrl = 'https://api.relay.link';
|
|
30
|
-
/** Relay quote endpoint. Anonymous access works at a 50-requests-per-minute tier. */
|
|
31
13
|
exports.relayQuoteUrl = `${exports.relayApiBaseUrl}/quote/v2`;
|
|
32
|
-
/** Relay requests endpoint; filters by origin or destination transaction hash. */
|
|
33
|
-
/**
|
|
34
|
-
* The request-lookup endpoint, used to poll a route's progress.
|
|
35
|
-
*
|
|
36
|
-
* v3 RATHER THAN v2 BECAUSE v2 IS GOING AWAY. Relay began staged rate limiting
|
|
37
|
-
* of `/requests/v2` on 2026-09-01 and retires it on 2026-11-24, saying so in a
|
|
38
|
-
* `deprecation` block on every v2 response. v3 REQUIRES `x-api-key` - it
|
|
39
|
-
* answers 400 without one, where v2 served anonymous callers from a shared
|
|
40
|
-
* pool - so a caller must send `relayRequestHeaders(yourRelayApiKey)`.
|
|
41
|
-
*/
|
|
42
14
|
exports.relayRequestsUrl = 'https://api.relay.link/requests/v3';
|
|
43
|
-
/**
|
|
44
|
-
* Builds the headers for a Relay request. `apiKey` is Relay's `x-api-key`
|
|
45
|
-
* value. This package ships no key: the caller supplies its own (the Gibs
|
|
46
|
-
* interface keeps its key in `packages/ui/src/lib/config.ts`).
|
|
47
|
-
* Relay raises the account's rate limit and attributes traffic to it when the
|
|
48
|
-
* header is present.
|
|
49
|
-
*
|
|
50
|
-
* When `apiKey` is absent or an empty string, the returned headers carry NO
|
|
51
|
-
* `x-api-key` entry at all — not an empty one.
|
|
52
|
-
*
|
|
53
|
-
* WHETHER THAT IS SURVIVABLE DEPENDS ENTIRELY ON WHICH ENDPOINT IS BEING CALLED,
|
|
54
|
-
* and this note used to say only the reassuring half. Measured against the live
|
|
55
|
-
* service:
|
|
56
|
-
*
|
|
57
|
-
* POST /quote no key -> 200 routing works anonymously
|
|
58
|
-
* GET /requests/v3 no key -> 400 "headers must have required
|
|
59
|
-
* property 'x-api-key'"
|
|
60
|
-
*
|
|
61
|
-
* So a missing key is a normal operating state for ROUTING — a reader on a
|
|
62
|
-
* local build or the anonymous InterPlanetary File System deployment still gets
|
|
63
|
-
* real quotes, and clearing the key disables attribution rather than the
|
|
64
|
-
* product. It is NOT survivable for STATUS. Every status poll from a keyless
|
|
65
|
-
* build fails, which means a consolidated record never learns its provider
|
|
66
|
-
* finished, never records the entry-chain transaction, and never releases from
|
|
67
|
-
* the pending list. That is not a degraded rate limit; it is the feature not
|
|
68
|
-
* working at all, silently.
|
|
69
|
-
*/
|
|
70
15
|
const relayRequestHeaders = (apiKey) => {
|
|
71
16
|
const headers = { 'Content-Type': 'application/json' };
|
|
72
17
|
if (apiKey) {
|
|
@@ -75,158 +20,48 @@ const relayRequestHeaders = (apiKey) => {
|
|
|
75
20
|
return headers;
|
|
76
21
|
};
|
|
77
22
|
exports.relayRequestHeaders = relayRequestHeaders;
|
|
78
|
-
/**
|
|
79
|
-
* Gibs Finance's own Relay `referrer`, for callers that want to attribute to
|
|
80
|
-
* Gibs Finance. The request builders do NOT default to it: pass it, or your
|
|
81
|
-
* own, as `relayReferrer` on the request. Relay reads any `referrer` as "a
|
|
82
|
-
* referrer was supplied" and then requires an API key, so a default would
|
|
83
|
-
* break every caller without one.
|
|
84
|
-
*/
|
|
85
23
|
exports.relayReferrer = referral_js_1.referralIntegrator;
|
|
86
|
-
/**
|
|
87
|
-
* Application fee in basis points charged on Relay routes. Ten basis points is
|
|
88
|
-
* one tenth of a percent. Sent as `appFees[0].fee` when a payout recipient is
|
|
89
|
-
* configured; absent entirely when the recipient is missing.
|
|
90
|
-
*/
|
|
91
24
|
exports.relayReferralFeeBasisPoints = referral_js_1.defaultReferralFeeBasisPoints;
|
|
92
25
|
var referral_js_2 = require("./referral.js");
|
|
93
26
|
Object.defineProperty(exports, "relayReferralRecipient", { enumerable: true, get: function () { return referral_js_2.relayReferralRecipient; } });
|
|
94
|
-
/** Extra gas added to the destination budget to cover a prepended approval call. */
|
|
95
27
|
exports.relayApprovalGasBuffer = 60000n;
|
|
96
|
-
/**
|
|
97
|
-
* Relay's chain identifiers and their display names live in `chain-names.ts`
|
|
98
|
-
* so the route-step normalizer can name a Relay chain without importing this
|
|
99
|
-
* module, which imports it. Re-exported here because callers reach for them
|
|
100
|
-
* alongside the rest of the Relay surface.
|
|
101
|
-
*/
|
|
102
28
|
var chain_names_js_2 = require("./chain-names.js");
|
|
103
29
|
Object.defineProperty(exports, "relayChainIds", { enumerable: true, get: function () { return chain_names_js_2.relayChainIds; } });
|
|
104
30
|
Object.defineProperty(exports, "relayChainNames", { enumerable: true, get: function () { return chain_names_js_2.relayChainNames; } });
|
|
105
|
-
/**
|
|
106
|
-
* Relay's pseudo chain identifiers, mapped to the ecosystem each belongs to.
|
|
107
|
-
* Data rather than a branch chain, so registering another Relay origin is one
|
|
108
|
-
* entry here instead of another conditional.
|
|
109
|
-
*/
|
|
110
31
|
const ecosystemByRelayChainId = new Map([
|
|
111
32
|
[chain_names_js_1.relayChainIds.solana, 'svm'],
|
|
112
|
-
// two chain ids, one ecosystem: the mapping is many-to-one by design
|
|
113
33
|
[chain_names_js_1.relayChainIds.eclipse, 'svm'],
|
|
114
34
|
[chain_names_js_1.relayChainIds.bitcoin, 'bvm'],
|
|
115
35
|
[chain_names_js_1.relayChainIds.tron, 'tvm'],
|
|
116
36
|
[chain_names_js_1.relayChainIds.ton, 'tonvm'],
|
|
117
37
|
[chain_names_js_1.relayChainIds.hyperliquid, 'hypevm'],
|
|
118
38
|
]);
|
|
119
|
-
/**
|
|
120
|
-
* The chains a reader pays by hand, mapped to the ecosystem each belongs to.
|
|
121
|
-
*
|
|
122
|
-
* KEPT APART FROM THE RELAY MAP ABOVE, because none of these is a Relay chain
|
|
123
|
-
* and a map named for Relay should not claim one. They are here at all because
|
|
124
|
-
* {@link ecosystemByChainId} answers `evm` for every identifier it does not
|
|
125
|
-
* know. An unregistered Zcash identifier would therefore read as an Ethereum
|
|
126
|
-
* chain — which has a wallet, a signer and a transaction — and the reader would
|
|
127
|
-
* be asked to sign on a chain they do not hold.
|
|
128
|
-
*
|
|
129
|
-
* Typed `Record<DepositAddressChain, Ecosystem>` rather than `Map<number, …>`
|
|
130
|
-
* so a chain added to {@link depositAddressChainIds} without an ecosystem
|
|
131
|
-
* here is a compile error. This is the table finding this danger is about: a
|
|
132
|
-
* silent miss is exactly the "reads as Ethereum" failure the comment above
|
|
133
|
-
* warns against, and a compile error is the only guard that cannot be
|
|
134
|
-
* forgotten.
|
|
135
|
-
*/
|
|
136
39
|
const ecosystemByDepositAddressChain = {
|
|
137
40
|
zcash: 'zcash',
|
|
138
41
|
};
|
|
139
|
-
/** {@link ecosystemByDepositAddressChain}, keyed by chain id for lookup. */
|
|
140
42
|
const ecosystemByDepositAddressChainId = new Map(Object.keys(chain_names_js_1.depositAddressChainIds).map((chain) => [
|
|
141
43
|
chain_names_js_1.depositAddressChainIds[chain],
|
|
142
44
|
ecosystemByDepositAddressChain[chain],
|
|
143
45
|
]));
|
|
144
|
-
/**
|
|
145
|
-
* Maps a chain identifier to its virtual-machine ecosystem. Relay's non-Ethereum
|
|
146
|
-
* pseudo chain identifiers map to their own ecosystem; every other identifier
|
|
147
|
-
* (every Ethereum Virtual Machine chain) maps to `evm`. Total — never throws.
|
|
148
|
-
*
|
|
149
|
-
* Lives here rather than in `ecosystems.ts` because it depends on
|
|
150
|
-
* `relayChainIds` (defined in this file); the `Ecosystem` import is type-only,
|
|
151
|
-
* so `ecosystems.ts` stays a dependency-free leaf and no import cycle is formed.
|
|
152
|
-
*
|
|
153
|
-
* @param chainId - a chain identifier (an Ethereum chain id, or a Relay pseudo id)
|
|
154
|
-
* @returns the ecosystem that chain belongs to
|
|
155
|
-
*/
|
|
156
46
|
const ecosystemByChainId = (chainId) => ecosystemByRelayChainId.get(chainId) ?? ecosystemByDepositAddressChainId.get(chainId) ?? 'evm';
|
|
157
47
|
exports.ecosystemByChainId = ecosystemByChainId;
|
|
158
|
-
/**
|
|
159
|
-
* Relay's native-currency address strings, used verbatim as `originCurrency`
|
|
160
|
-
* when the origin pays in the chain's native asset.
|
|
161
|
-
*
|
|
162
|
-
* Source: https://api.relay.link/chains.
|
|
163
|
-
*/
|
|
164
48
|
exports.relayNativeCurrencyAddresses = {
|
|
165
|
-
/**
|
|
166
|
-
* Ethereum Virtual Machine native currency (Ether, native gas tokens). The
|
|
167
|
-
* all-zero address Relay uses across every Ethereum Virtual Machine chain.
|
|
168
|
-
*/
|
|
169
49
|
ethereumVirtualMachine: '0x0000000000000000000000000000000000000000',
|
|
170
|
-
/**
|
|
171
|
-
* Solana native currency (SOL), addressed by the System Program. Nine
|
|
172
|
-
* decimals.
|
|
173
|
-
*/
|
|
174
50
|
solana: '11111111111111111111111111111111',
|
|
175
|
-
/** Bitcoin native currency (BTC). Eight decimals. */
|
|
176
51
|
bitcoin: 'bc1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqmql8k8',
|
|
177
|
-
/** Tron native currency (TRX). Six decimals. */
|
|
178
52
|
tron: 'T9yD14Nj9j7xAB4dbGeiX9h8unkKHxuWwb',
|
|
179
|
-
/**
|
|
180
|
-
* The Open Network's native currency as Relay reports it: Gram, NOT the
|
|
181
|
-
* Toncoin gas asset. Nine decimals.
|
|
182
|
-
*/
|
|
183
53
|
ton: 'EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM9c',
|
|
184
|
-
/**
|
|
185
|
-
* Hyperliquid's native currency as Relay reports it: USD Coin, NOT the Hype
|
|
186
|
-
* gas asset, addressed by a sixteen-byte HyperCore token identifier. Eight
|
|
187
|
-
* decimals. Deliberately NOT the twenty-byte all-zero Ethereum address.
|
|
188
|
-
*/
|
|
189
54
|
hyperliquid: '0x00000000000000000000000000000000',
|
|
190
55
|
};
|
|
191
|
-
/**
|
|
192
|
-
* Converts a slippage fraction into the basis-point string Relay expects.
|
|
193
|
-
*
|
|
194
|
-
* @param slippage - tolerance as a fraction (0.005 means half a percent)
|
|
195
|
-
* @returns basis points as a string (0.005 becomes "50")
|
|
196
|
-
*/
|
|
197
56
|
const slippageToBasisPoints = (slippage) => Math.round(slippage * 10_000).toString();
|
|
198
57
|
exports.slippageToBasisPoints = slippageToBasisPoints;
|
|
199
|
-
/**
|
|
200
|
-
* The `referrer` field of a Relay request body, present only when the caller
|
|
201
|
-
* named one. Relay reads any `referrer`, an empty one included, as "a referrer
|
|
202
|
-
* was supplied" and then requires an API key, so absence is the safe default.
|
|
203
|
-
*
|
|
204
|
-
* @param request - carries the caller's `relayReferrer`, if any
|
|
205
|
-
* @returns `{ referrer }`, or an empty object
|
|
206
|
-
*/
|
|
207
58
|
const relayReferrerField = (request) => {
|
|
208
59
|
const referrer = (0, referral_js_1.resolveAttribution)(request.relayReferrer, undefined);
|
|
209
60
|
return referrer === undefined ? {} : { referrer };
|
|
210
61
|
};
|
|
211
62
|
exports.relayReferrerField = relayReferrerField;
|
|
212
|
-
/**
|
|
213
|
-
* Builds the Relay contract-call quote request from a provider-agnostic
|
|
214
|
-
* consolidated request. The omnibridge entry call becomes the final `txs`
|
|
215
|
-
* entry; when it needs an ERC20 allowance (the relayTokens shape, where
|
|
216
|
-
* `approvalTarget` is set) an `approve` call is prepended so Relay's executor
|
|
217
|
-
* grants it before relaying.
|
|
218
|
-
*
|
|
219
|
-
* @returns the request body, or null when the inputs cannot form a valid call
|
|
220
|
-
*/
|
|
221
63
|
const buildRelayQuoteRequest = (request) => {
|
|
222
64
|
const { destinationCall, toAmount } = request;
|
|
223
|
-
// A DIRECT ROUTE — no omnibridge leg, so nothing to call on arrival.
|
|
224
|
-
//
|
|
225
|
-
// Solved FORWARDS rather than backwards, which is the whole difference. A
|
|
226
|
-
// route into the omnibridge must deliver an exact amount to the entry call,
|
|
227
|
-
// so it asks Relay for an exact OUTPUT. Here the reader says what they are
|
|
228
|
-
// spending and the delivered amount is whatever the market gives, so it asks
|
|
229
|
-
// for an exact INPUT and names a `recipient` instead of a transaction to run.
|
|
230
65
|
if (destinationCall === undefined) {
|
|
231
66
|
const fromAmount = request.fromAmount;
|
|
232
67
|
if (fromAmount === undefined || fromAmount <= 0n) {
|
|
@@ -241,12 +76,7 @@ const buildRelayQuoteRequest = (request) => {
|
|
|
241
76
|
destinationCurrency: request.toTokenAddress,
|
|
242
77
|
amount: fromAmount.toString(),
|
|
243
78
|
tradeType: 'EXACT_INPUT',
|
|
244
|
-
// Where the funds land. On a route through the omnibridge this is encoded
|
|
245
|
-
// inside the entry call; with no call to carry it, Relay is told directly.
|
|
246
79
|
recipient: request.recipient,
|
|
247
|
-
// Same rule as the omnibridge path below: Relay refunds on the ORIGIN
|
|
248
|
-
// chain, so a non-Ethereum origin cannot be refunded to an Ethereum
|
|
249
|
-
// fallback address and must name its own.
|
|
250
80
|
refundTo: nonEthereumOriginDirect ? request.fromAddress : request.fallbackAddress,
|
|
251
81
|
...(0, exports.relayReferrerField)(request),
|
|
252
82
|
...(request.slippage === undefined
|
|
@@ -275,21 +105,12 @@ const buildRelayQuoteRequest = (request) => {
|
|
|
275
105
|
if (toAmount <= 0n) {
|
|
276
106
|
return null;
|
|
277
107
|
}
|
|
278
|
-
// A NATIVE ENTRY (`wrapAndRelayTokens`) CARRIES VALUE, and Relay's solver
|
|
279
|
-
// attaches it: a dry quote with this exact call simulates it on the entry
|
|
280
|
-
// chain (see `providers.ts`'s `destinationCallCarriesNativeValue` for the
|
|
281
|
-
// measurement). Relay delivers the native coin itself, so no approval is
|
|
282
|
-
// prepended — the call's own `approvalTarget` is null for this shape.
|
|
283
108
|
const entryCall = {
|
|
284
109
|
to: destinationCall.to,
|
|
285
110
|
value: destinationCall.value.toString(),
|
|
286
111
|
data: destinationCall.data,
|
|
287
112
|
};
|
|
288
113
|
const needsApproval = destinationCall.approvalTarget !== null;
|
|
289
|
-
// grant an unbounded allowance, the standard executor pattern: Relay's
|
|
290
|
-
// Multicaller holds the bridged tokens only transiently during the call
|
|
291
|
-
// sequence, and an exact allowance would strand funds if the entry call ever
|
|
292
|
-
// pulls a balance rather than the fixed amount encoded in its calldata
|
|
293
114
|
const approvalCall = needsApproval
|
|
294
115
|
? {
|
|
295
116
|
to: request.toTokenAddress,
|
|
@@ -303,24 +124,10 @@ const buildRelayQuoteRequest = (request) => {
|
|
|
303
124
|
: null;
|
|
304
125
|
const txs = approvalCall ? [approvalCall, entryCall] : [entryCall];
|
|
305
126
|
const txsGasLimit = destinationCall.gasLimit + (needsApproval ? exports.relayApprovalGasBuffer : 0n);
|
|
306
|
-
// The omnibridge has two entry points: Ethereum and Binance Smart Chain. The
|
|
307
|
-
// destination chain MUST track the entry chain the request targets, because
|
|
308
|
-
// `destinationCurrency` is the entry-chain token address — pairing a
|
|
309
|
-
// Binance-side token with a hardcoded Ethereum destination makes Relay reject
|
|
310
|
-
// the quote with "Invalid input or output currency" (that token does not exist
|
|
311
|
-
// on Ethereum). Defaults to Ethereum, preserving the original single-entry
|
|
312
|
-
// behavior when `toChainId` is omitted.
|
|
313
127
|
const destinationChainId = request.toChainId ?? Number(config_js_1.Chains.ETH);
|
|
314
128
|
const nonEthereumOrigin = (0, consolidated_quote_js_1.isNonEthereumVirtualMachineOrigin)(request);
|
|
315
|
-
// Relay always refunds a failed route on the ORIGIN chain. For an Ethereum
|
|
316
|
-
// Virtual Machine origin the user's Ethereum-side fallback address doubles as
|
|
317
|
-
// that origin refund target (unchanged behavior). For a non-Ethereum origin
|
|
318
|
-
// the fallback address is an Ethereum address Relay cannot refund to on the
|
|
319
|
-
// origin chain, so the refund must go to the user's own origin-chain address.
|
|
320
129
|
const refundTo = nonEthereumOrigin ? request.fromAddress : request.fallbackAddress;
|
|
321
|
-
// Relay's Solana fee sponsorship; only included for a Solana origin that names a payer.
|
|
322
130
|
const includeDepositFeePayer = request.originVmType === 'svm' && request.solanaFeePayer !== undefined;
|
|
323
|
-
// Relay's Bitcoin pay-to-script-hash public key; only for a Bitcoin origin that supplies one.
|
|
324
131
|
const includeBitcoinPublicKey = request.originVmType === 'bvm' && request.bitcoinPublicKey !== undefined;
|
|
325
132
|
return {
|
|
326
133
|
user: request.fromAddress,
|
|
@@ -330,7 +137,6 @@ const buildRelayQuoteRequest = (request) => {
|
|
|
330
137
|
destinationCurrency: request.toTokenAddress,
|
|
331
138
|
amount: toAmount.toString(),
|
|
332
139
|
tradeType: 'EXACT_OUTPUT',
|
|
333
|
-
// origin-chain refund target — Relay's only failure remedy for this route
|
|
334
140
|
refundTo,
|
|
335
141
|
...(0, exports.relayReferrerField)(request),
|
|
336
142
|
txs,
|
|
@@ -349,12 +155,6 @@ const buildRelayQuoteRequest = (request) => {
|
|
|
349
155
|
};
|
|
350
156
|
exports.buildRelayQuoteRequest = buildRelayQuoteRequest;
|
|
351
157
|
const isHexString = (value) => typeof value === 'string' && value.startsWith('0x');
|
|
352
|
-
/**
|
|
353
|
-
* Parses a quantity Relay may report as a hex string, a decimal string, or a
|
|
354
|
-
* number into a bigint.
|
|
355
|
-
*
|
|
356
|
-
* @returns the bigint value, or null when the input is not a parseable quantity
|
|
357
|
-
*/
|
|
358
158
|
const parseQuantity = (value) => {
|
|
359
159
|
if (typeof value === 'number' && Number.isInteger(value)) {
|
|
360
160
|
return BigInt(value);
|
|
@@ -375,11 +175,6 @@ const asRecord = (value) => {
|
|
|
375
175
|
}
|
|
376
176
|
return value;
|
|
377
177
|
};
|
|
378
|
-
/**
|
|
379
|
-
* Pulls the signable transaction out of a Relay step item.
|
|
380
|
-
*
|
|
381
|
-
* @returns the transaction data, or null when the item has no usable transaction
|
|
382
|
-
*/
|
|
383
178
|
const stepItemTransaction = (item) => {
|
|
384
179
|
const record = asRecord(item);
|
|
385
180
|
const data = asRecord(record?.data);
|
|
@@ -391,13 +186,6 @@ const stepItemTransaction = (item) => {
|
|
|
391
186
|
}
|
|
392
187
|
return data;
|
|
393
188
|
};
|
|
394
|
-
/**
|
|
395
|
-
* Pulls a Solana instruction set out of a Relay deposit step item. A Solana
|
|
396
|
-
* deposit carries `data.instructions[]` plus the address-lookup-table addresses
|
|
397
|
-
* to compile a versioned transaction, and no `to`/`data` hex fields.
|
|
398
|
-
*
|
|
399
|
-
* @returns the instruction set, or null when the item is not a Solana deposit
|
|
400
|
-
*/
|
|
401
189
|
const stepItemSolanaInstructions = (item) => {
|
|
402
190
|
const data = asRecord(asRecord(item)?.data);
|
|
403
191
|
if (!data || !Array.isArray(data.instructions)) {
|
|
@@ -417,13 +205,6 @@ const stepItemSolanaInstructions = (item) => {
|
|
|
417
205
|
: [];
|
|
418
206
|
return { instructions, addressLookupTableAddresses: lookupTables };
|
|
419
207
|
};
|
|
420
|
-
/**
|
|
421
|
-
* Pulls a Bitcoin partially-signed transaction out of a Relay deposit step
|
|
422
|
-
* item. Relay hex-encodes it (the "psbt\xff" magic, `70736274ff…`) and it is not
|
|
423
|
-
* `0x`-prefixed, so the Ethereum hex gate does not match it.
|
|
424
|
-
*
|
|
425
|
-
* @returns the partially-signed transaction, or null when the item is not a Bitcoin deposit
|
|
426
|
-
*/
|
|
427
208
|
const stepItemBitcoinPsbt = (item) => {
|
|
428
209
|
const data = asRecord(asRecord(item)?.data);
|
|
429
210
|
if (!data || typeof data.psbt !== 'string' || data.psbt === '') {
|
|
@@ -431,13 +212,6 @@ const stepItemBitcoinPsbt = (item) => {
|
|
|
431
212
|
}
|
|
432
213
|
return { psbt: data.psbt };
|
|
433
214
|
};
|
|
434
|
-
/**
|
|
435
|
-
* Normalizes a typed-data type table, keeping only well-formed `{name, type}`
|
|
436
|
-
* fields. Shared by the Hyperliquid action and its authorization, which carry
|
|
437
|
-
* the same table shape under different keys.
|
|
438
|
-
*
|
|
439
|
-
* @returns the type table; empty when the payload carries none
|
|
440
|
-
*/
|
|
441
215
|
const typedDataTypes = (value) => {
|
|
442
216
|
const record = asRecord(value);
|
|
443
217
|
if (!record) {
|
|
@@ -457,14 +231,6 @@ const typedDataTypes = (value) => {
|
|
|
457
231
|
});
|
|
458
232
|
return Object.fromEntries(entries);
|
|
459
233
|
};
|
|
460
|
-
/**
|
|
461
|
-
* Pulls a Tron contract call out of a Relay deposit step item. Tron's wire shape
|
|
462
|
-
* nests snake_case fields under `parameter` and names the contract kind in
|
|
463
|
-
* `type`; its `data` is bare hex with no `0x` prefix, so the Ethereum hex gate
|
|
464
|
-
* never claims it.
|
|
465
|
-
*
|
|
466
|
-
* @returns the contract call, or null when the item is not a Tron deposit
|
|
467
|
-
*/
|
|
468
234
|
const stepItemTronContract = (item) => {
|
|
469
235
|
const data = asRecord(asRecord(item)?.data);
|
|
470
236
|
if (!data || typeof data.type !== 'string') {
|
|
@@ -477,8 +243,6 @@ const stepItemTronContract = (item) => {
|
|
|
477
243
|
const ownerAddress = parameter.owner_address;
|
|
478
244
|
const contractAddress = parameter.contract_address;
|
|
479
245
|
const callData = parameter.data;
|
|
480
|
-
// require every field we map, so a wire-shape change fails closed rather than
|
|
481
|
-
// producing a deposit with silently empty addresses
|
|
482
246
|
if (typeof ownerAddress !== 'string' ||
|
|
483
247
|
typeof contractAddress !== 'string' ||
|
|
484
248
|
typeof callData !== 'string') {
|
|
@@ -488,18 +252,10 @@ const stepItemTronContract = (item) => {
|
|
|
488
252
|
contractType: data.type,
|
|
489
253
|
ownerAddress,
|
|
490
254
|
contractAddress,
|
|
491
|
-
// a call that sends no TRX omits the field rather than sending zero
|
|
492
255
|
callValue: parseQuantity(parameter.call_value) ?? 0n,
|
|
493
256
|
data: callData,
|
|
494
257
|
};
|
|
495
258
|
};
|
|
496
|
-
/**
|
|
497
|
-
* Pulls a TON message list out of a Relay deposit step item. TON wallets send a
|
|
498
|
-
* list of messages rather than one transaction, and each payload is a base64
|
|
499
|
-
* bag-of-cells rather than hex.
|
|
500
|
-
*
|
|
501
|
-
* @returns the message list, or null when the item is not a TON deposit
|
|
502
|
-
*/
|
|
503
259
|
const stepItemTonMessages = (item) => {
|
|
504
260
|
const data = asRecord(asRecord(item)?.data);
|
|
505
261
|
if (!data || !Array.isArray(data.messages)) {
|
|
@@ -519,9 +275,7 @@ const stepItemTonMessages = (item) => {
|
|
|
519
275
|
to: record.to,
|
|
520
276
|
value,
|
|
521
277
|
body: record.body,
|
|
522
|
-
// mode 0 sends with no special flags, TON's own default
|
|
523
278
|
mode: typeof record.mode === 'number' ? record.mode : 0,
|
|
524
|
-
// absent means non-bouncing; only an explicit true bounces
|
|
525
279
|
bounce: record.bounce === true,
|
|
526
280
|
from: typeof record.from === 'string' ? record.from : null,
|
|
527
281
|
},
|
|
@@ -532,14 +286,6 @@ const stepItemTonMessages = (item) => {
|
|
|
532
286
|
}
|
|
533
287
|
return { messages };
|
|
534
288
|
};
|
|
535
|
-
/**
|
|
536
|
-
* Pulls the typed-data action out of a Relay Hyperliquid deposit step item.
|
|
537
|
-
* Nothing here is broadcast: the action is signed and posted to Hyperliquid's
|
|
538
|
-
* API, so there is no `to`, no calldata, and no gas for the Ethereum hex gate to
|
|
539
|
-
* match.
|
|
540
|
-
*
|
|
541
|
-
* @returns the action, or null when the item is not a Hyperliquid deposit
|
|
542
|
-
*/
|
|
543
289
|
const stepItemHyperliquidAction = (item) => {
|
|
544
290
|
const data = asRecord(asRecord(item)?.data);
|
|
545
291
|
if (!data || typeof data.eip712PrimaryType !== 'string') {
|
|
@@ -556,15 +302,6 @@ const stepItemHyperliquidAction = (item) => {
|
|
|
556
302
|
nonce: parseQuantity(data.nonce) ?? 0n,
|
|
557
303
|
};
|
|
558
304
|
};
|
|
559
|
-
/**
|
|
560
|
-
* Finds the authorization a Hyperliquid deposit must complete before its action
|
|
561
|
-
* can be submitted. It arrives as its own `signature` step ahead of the deposit,
|
|
562
|
-
* which the deposit scan skips because it carries no deposit shape — so it is
|
|
563
|
-
* collected separately and attached to the deposit, rather than lost.
|
|
564
|
-
*
|
|
565
|
-
* @param steps - every step on the quote
|
|
566
|
-
* @returns the authorization, or null when the quote carries none
|
|
567
|
-
*/
|
|
568
305
|
const stepAuthorization = (steps) => {
|
|
569
306
|
for (const step of steps) {
|
|
570
307
|
if (step.kind !== 'signature' || !Array.isArray(step.items)) {
|
|
@@ -598,17 +335,6 @@ const stepAuthorization = (steps) => {
|
|
|
598
335
|
}
|
|
599
336
|
return null;
|
|
600
337
|
};
|
|
601
|
-
/**
|
|
602
|
-
* Recognizes the one deposit shape a Relay step item carries, trying the
|
|
603
|
-
* Ethereum transaction shape first (the only one gated on hex `to`/`data`), then
|
|
604
|
-
* each non-Ethereum shape in turn. Every shape is keyed on a field the others do
|
|
605
|
-
* not carry, so the recognizers are mutually exclusive and the order is a
|
|
606
|
-
* cheapest-check-first convenience rather than a correctness requirement — a
|
|
607
|
-
* property the tests pin, because a future overlap would silently mis-route a
|
|
608
|
-
* deposit to the wrong ecosystem's signer.
|
|
609
|
-
*
|
|
610
|
-
* @returns the discriminated deposit, or null when the item carries none
|
|
611
|
-
*/
|
|
612
338
|
const stepItemDeposit = (item) => {
|
|
613
339
|
const transaction = stepItemTransaction(item);
|
|
614
340
|
if (transaction) {
|
|
@@ -636,13 +362,6 @@ const stepItemDeposit = (item) => {
|
|
|
636
362
|
}
|
|
637
363
|
return null;
|
|
638
364
|
};
|
|
639
|
-
/**
|
|
640
|
-
* Extracts the ERC20 spender from a Relay `approve` step so our own approval
|
|
641
|
-
* machinery can grant it. The origin token, not Relay, decides the spender, so
|
|
642
|
-
* we decode it from the ready-made approval calldata rather than guessing.
|
|
643
|
-
*
|
|
644
|
-
* @returns the spender address, or null when the step is absent or undecodable
|
|
645
|
-
*/
|
|
646
365
|
const approvalSpender = (steps) => {
|
|
647
366
|
const approveStep = steps.find((step) => step.id === 'approve');
|
|
648
367
|
if (!approveStep) {
|
|
@@ -664,18 +383,10 @@ const approvalSpender = (steps) => {
|
|
|
664
383
|
}
|
|
665
384
|
}
|
|
666
385
|
catch {
|
|
667
|
-
// not an approve call we recognize; keep scanning
|
|
668
386
|
}
|
|
669
387
|
}
|
|
670
388
|
return null;
|
|
671
389
|
};
|
|
672
|
-
/**
|
|
673
|
-
* Finds the deposit the user signs after any approval — the first
|
|
674
|
-
* deposit-bearing item on a step that is not the `approve` step — and reports
|
|
675
|
-
* which source ecosystem's shape it carries.
|
|
676
|
-
*
|
|
677
|
-
* @returns the step and its discriminated deposit, or null when none is present
|
|
678
|
-
*/
|
|
679
390
|
const depositStep = (steps) => {
|
|
680
391
|
for (const step of steps) {
|
|
681
392
|
if (step.id === 'approve') {
|
|
@@ -694,24 +405,6 @@ const depositStep = (steps) => {
|
|
|
694
405
|
}
|
|
695
406
|
return null;
|
|
696
407
|
};
|
|
697
|
-
/**
|
|
698
|
-
* Maps a discriminated Relay deposit onto the shared `OriginDeposit` union.
|
|
699
|
-
* Ethereum reads its chain id from the deposit transaction; the non-Ethereum
|
|
700
|
-
* variants have no chain id on the deposit payload, so they read it from the
|
|
701
|
-
* quote's origin currency (`details.currencyIn.currency.chainId`).
|
|
702
|
-
*
|
|
703
|
-
* The non-Ethereum variants are matched by an EXHAUSTIVE switch rather than a
|
|
704
|
-
* trailing fallback: an unhandled variant must be a compile error, because
|
|
705
|
-
* quietly treating one ecosystem's deposit as another's would hand a payload to
|
|
706
|
-
* the wrong signer.
|
|
707
|
-
*
|
|
708
|
-
* @param found - the deposit and the step it was found on
|
|
709
|
-
* @param currencyIn - the quote's `details.currencyIn`, the only source of an
|
|
710
|
-
* origin chain id for a non-Ethereum deposit
|
|
711
|
-
* @param steps - every step on the quote, needed to collect the Hyperliquid
|
|
712
|
-
* authorization that arrives as its own step
|
|
713
|
-
* @returns the origin deposit, or null when a required field is unparseable
|
|
714
|
-
*/
|
|
715
408
|
const relayOriginDeposit = (found, currencyIn, steps) => {
|
|
716
409
|
const { step, deposit } = found;
|
|
717
410
|
if (deposit.kind === 'evm') {
|
|
@@ -768,14 +461,6 @@ const relayOriginDeposit = (found, currencyIn, steps) => {
|
|
|
768
461
|
}
|
|
769
462
|
}
|
|
770
463
|
};
|
|
771
|
-
/**
|
|
772
|
-
* Normalizes a Relay `/quote/v2` response into the shared consolidated quote
|
|
773
|
-
* shape. The origin approval Relay returns as its own step is folded back into
|
|
774
|
-
* `approvalAddress` so the executor raises it through the same path as LI.FI;
|
|
775
|
-
* the deposit step becomes the single `originDeposit`.
|
|
776
|
-
*
|
|
777
|
-
* @returns the normalized quote, or null when the payload shape is unexpected
|
|
778
|
-
*/
|
|
779
464
|
const parseRelayQuote = (payload) => {
|
|
780
465
|
const quote = asRecord(payload);
|
|
781
466
|
if (!quote) {
|
|
@@ -803,8 +488,6 @@ const parseRelayQuote = (payload) => {
|
|
|
803
488
|
if (!found) {
|
|
804
489
|
return null;
|
|
805
490
|
}
|
|
806
|
-
// the identifier lives on the steps in the verified response shape; fall back
|
|
807
|
-
// through a top-level field so a future nesting change does not reject quotes
|
|
808
491
|
const requestId = typeof quote.requestId === 'string'
|
|
809
492
|
? quote.requestId
|
|
810
493
|
: steps.map((step) => step.requestId).find((id) => typeof id === 'string');
|
|
@@ -822,102 +505,39 @@ const parseRelayQuote = (payload) => {
|
|
|
822
505
|
tool: 'relay',
|
|
823
506
|
toolName: 'Relay',
|
|
824
507
|
fromAmount,
|
|
825
|
-
// WHAT THE ROUTE DELIVERS, WHEN ONLY RELAY KNOWS. An omnibridge route names
|
|
826
|
-
// its own delivered amount in the request and asks for an exact output, so
|
|
827
|
-
// this repeats what the caller already said. A direct route asks for an
|
|
828
|
-
// exact input, and the delivered amount exists nowhere until this answer.
|
|
829
|
-
// Undefined rather than zero when the field is missing: zero is a real
|
|
830
|
-
// quantity and would read as "this route delivers nothing".
|
|
831
508
|
...(() => {
|
|
832
509
|
const out = parseQuantity(asRecord(details?.currencyOut)?.amount);
|
|
833
510
|
return out === null ? {} : { toAmount: out };
|
|
834
511
|
})(),
|
|
835
512
|
fromAmountUsd: typeof currencyIn.amountUsd === 'string' ? currencyIn.amountUsd : null,
|
|
836
|
-
// The delivered side valued by the same answer that valued the paid side —
|
|
837
|
-
// see `ConsolidatedQuote.toAmountUsd` for why it may not come from anywhere
|
|
838
|
-
// else. Omitted rather than nulled when Relay leaves it out.
|
|
839
513
|
...(() => {
|
|
840
514
|
const outUsd = asRecord(details?.currencyOut)?.amountUsd;
|
|
841
515
|
return typeof outUsd === 'string' ? { toAmountUsd: outUsd } : {};
|
|
842
516
|
})(),
|
|
843
|
-
// a native origin token is pulled with no allowance, so no spender applies
|
|
844
517
|
approvalAddress: spender !== null && spender !== viem_1.zeroAddress ? spender : null,
|
|
845
518
|
executionDurationSeconds: details.timeEstimate,
|
|
846
|
-
// Relay's `steps` are operational (approve + deposit); the per-leg route
|
|
847
|
-
// lives in `details.route`, so the whole quote is normalized, not `steps`.
|
|
848
519
|
steps: (0, route_steps_js_1.normalizeRelaySteps)(quote),
|
|
849
520
|
originDeposit,
|
|
850
521
|
fees: (0, quote_fees_js_1.relayQuoteFees)(payload),
|
|
851
522
|
};
|
|
852
523
|
};
|
|
853
524
|
exports.parseRelayQuote = parseRelayQuote;
|
|
854
|
-
/**
|
|
855
|
-
* Builds the requests-lookup address for a Relay route BY ITS QUOTE
|
|
856
|
-
* IDENTIFIER.
|
|
857
|
-
*
|
|
858
|
-
* IT USED TO ASK BY ORIGIN TRANSACTION HASH, AND THAT RETURNED OTHER PEOPLE'S
|
|
859
|
-
* TRANSFERS. `/requests/v3` does not accept a `hash` filter: it ignores the
|
|
860
|
-
* parameter entirely and answers with the twenty most recent requests ACROSS
|
|
861
|
-
* ALL USERS. Measured, with two different origin hashes a minute apart:
|
|
862
|
-
*
|
|
863
|
-
* ?hash=0x447149ed… -> 20 requests, first is 8453:0x7d7c3de2… -> 4663:…
|
|
864
|
-
* ?hash=0xa650d2d7… -> the SAME 20 requests, same first entry
|
|
865
|
-
*
|
|
866
|
-
* `parseRelayStatus` reads `requests[0]`, so both of this account's transfers
|
|
867
|
-
* were updated from a stranger's — they took the same entry-chain transaction
|
|
868
|
-
* hash, and neither was their own. A transfer was reported finished because
|
|
869
|
-
* somebody else's had finished.
|
|
870
|
-
*
|
|
871
|
-
* `id` is the filter v3 actually honours. The same lookup by quote identifier
|
|
872
|
-
* returns exactly ONE request, and its `inTxs` name the origin transaction the
|
|
873
|
-
* reader really signed. The caller should assert that correspondence rather
|
|
874
|
-
* than trust it — see `checkConsolidatedRecord`.
|
|
875
|
-
*/
|
|
876
525
|
const relayStatusUrl = ({ quoteId }) => {
|
|
877
526
|
return (0, url_1.buildUrl)(exports.relayRequestsUrl, { id: quoteId });
|
|
878
527
|
};
|
|
879
528
|
exports.relayStatusUrl = relayStatusUrl;
|
|
880
|
-
/**
|
|
881
|
-
* Relay's request lifecycle states. Terminal states are `success` (the
|
|
882
|
-
* destination call filled), `failure`, and `refund` (made whole on the origin
|
|
883
|
-
* chain). Every other state is still in flight.
|
|
884
|
-
*/
|
|
885
529
|
const relayInFlightStatuses = ['waiting', 'depositing', 'pending', 'submitted', 'delayed'];
|
|
886
530
|
const isEthereumTransactionHash = (value) => typeof value === 'string' && /^0x[0-9a-fA-F]{64}$/.test(value);
|
|
887
|
-
/**
|
|
888
|
-
* Finds the destination-chain transaction hash among a Relay request's output
|
|
889
|
-
* transactions — the hash that gates the handover to the omnibridge indexer.
|
|
890
|
-
* The destination chain is the omnibridge entry chain the route targeted
|
|
891
|
-
* (Ethereum or Binance Smart Chain), so it is supplied by the caller rather
|
|
892
|
-
* than assumed.
|
|
893
|
-
*
|
|
894
|
-
* @param request - a Relay request record
|
|
895
|
-
* @param destinationChainId - the omnibridge entry chain the route targeted
|
|
896
|
-
* @returns the destination-chain transaction hash, or null when none recorded
|
|
897
|
-
*/
|
|
898
531
|
const outputTransactions = (request) => {
|
|
899
|
-
// RELAY NESTS THESE UNDER `data`. An earlier version read `request.outTxs`,
|
|
900
|
-
// which no response has ever carried: measured 2026-09-01 across a hundred
|
|
901
|
-
// live records, `request.outTxs` was present on ZERO and `request.data.outTxs`
|
|
902
|
-
// on every one. So this returned null for every completed route, and the
|
|
903
|
-
// interface reported DONE while linking nothing. The unit tests missed it
|
|
904
|
-
// because they were written to the same wrong shape as the parser.
|
|
905
532
|
const data = asRecord(request.data);
|
|
906
533
|
if (Array.isArray(data?.outTxs)) {
|
|
907
534
|
return data.outTxs;
|
|
908
535
|
}
|
|
909
|
-
// Kept as a fallback rather than deleted: it costs one array check, and a
|
|
910
|
-
// response that does flatten them still reads correctly.
|
|
911
536
|
if (Array.isArray(request.outTxs)) {
|
|
912
537
|
return request.outTxs;
|
|
913
538
|
}
|
|
914
539
|
return [];
|
|
915
540
|
};
|
|
916
|
-
/**
|
|
917
|
-
* The transaction hash on one output entry. `/requests/v2` names the field
|
|
918
|
-
* `hash` and `/requests/v3` names it `txHash`; both appear in the wild, so both
|
|
919
|
-
* are read rather than choosing by endpoint version.
|
|
920
|
-
*/
|
|
921
541
|
const outputHashOf = (entry) => {
|
|
922
542
|
const record = asRecord(entry);
|
|
923
543
|
if (isEthereumTransactionHash(record?.txHash)) {
|
|
@@ -947,19 +567,6 @@ const destinationOutputHash = (request, destinationChainId) => {
|
|
|
947
567
|
}
|
|
948
568
|
return null;
|
|
949
569
|
};
|
|
950
|
-
/**
|
|
951
|
-
* Maps a Relay request status onto the provider-agnostic consolidated status.
|
|
952
|
-
* `success` reports `DONE`/`COMPLETED` because for this route the destination
|
|
953
|
-
* fill IS our omnibridge entry call; `refund` reports `DONE`/`REFUNDED` because
|
|
954
|
-
* the user was made whole on the origin chain. Relay never strands funds on
|
|
955
|
-
* Ethereum, so the partial/stranded status LI.FI can return has no analogue.
|
|
956
|
-
*
|
|
957
|
-
* @param payload - a `/requests/v2?hash=` response body
|
|
958
|
-
* @param options.destinationChainId - the omnibridge entry chain the route
|
|
959
|
-
* targeted (Ethereum or Binance Smart Chain); defaults to Ethereum,
|
|
960
|
-
* preserving the original single-entry behavior
|
|
961
|
-
* @returns the normalized status, or null when no matching request is present
|
|
962
|
-
*/
|
|
963
570
|
const parseRelayStatus = (payload, { destinationChainId = Number(config_js_1.Chains.ETH) } = {}) => {
|
|
964
571
|
const data = asRecord(payload);
|
|
965
572
|
if (!data) {
|
|
@@ -990,7 +597,6 @@ const parseRelayStatus = (payload, { destinationChainId = Number(config_js_1.Cha
|
|
|
990
597
|
if (relayInFlightStatuses.some((inFlight) => inFlight === status)) {
|
|
991
598
|
return { status: 'PENDING', substatus: status, receivingTxHash };
|
|
992
599
|
}
|
|
993
|
-
// an unrecognized status is treated as still indexing rather than terminal
|
|
994
600
|
return { status: 'NOT_FOUND', substatus: status, receivingTxHash };
|
|
995
601
|
};
|
|
996
602
|
exports.parseRelayStatus = parseRelayStatus;
|