@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.
- package/LICENSE +15 -0
- package/README.md +234 -432
- package/dist/abis.d.ts +1 -0
- package/dist/bridge-limits.d.ts +103 -0
- package/dist/bridge-limits.js +84 -0
- package/dist/chain-info.d.ts +169 -0
- package/dist/chain-info.js +410 -0
- package/dist/chain-names.d.ts +160 -0
- package/dist/chain-names.js +200 -0
- package/dist/chains.d.ts +65 -0
- package/dist/chains.js +284 -0
- package/dist/config.d.ts +216 -0
- package/dist/config.js +493 -0
- package/dist/consolidated-quote.d.ts +554 -0
- package/dist/consolidated-quote.js +773 -0
- package/dist/destination-calldata.d.ts +118 -0
- package/dist/destination-calldata.js +152 -0
- package/dist/ecosystems.d.ts +217 -0
- package/dist/ecosystems.js +288 -0
- package/dist/fee-type.d.ts +10 -0
- package/dist/fee-type.js +9 -0
- package/dist/hyperliquid-execution.d.ts +152 -0
- package/dist/hyperliquid-execution.js +168 -0
- package/dist/image-links.d.ts +117 -0
- package/dist/image-links.js +142 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +20 -0
- package/dist/lifi-execution-guard.d.ts +199 -0
- package/dist/lifi-execution-guard.js +400 -0
- package/dist/near-intents-conformance.d.ts +85 -0
- package/dist/near-intents-conformance.js +329 -0
- package/dist/near-intents-route.d.ts +47 -0
- package/dist/near-intents-route.js +265 -0
- package/dist/near-intents.d.ts +524 -0
- package/dist/near-intents.js +1055 -0
- package/dist/origin-deposit.d.ts +326 -0
- package/dist/origin-deposit.js +68 -0
- package/dist/pre-quote.d.ts +198 -0
- package/dist/pre-quote.js +175 -0
- package/dist/prices.d.ts +107 -0
- package/dist/prices.js +162 -0
- package/dist/providers.d.ts +221 -0
- package/dist/providers.js +157 -0
- package/dist/quote-fees.d.ts +102 -0
- package/dist/quote-fees.js +195 -0
- package/dist/referral.d.ts +77 -0
- package/dist/referral.js +72 -0
- package/dist/relay-currencies.d.ts +47 -0
- package/dist/relay-currencies.js +89 -0
- package/dist/relay-quote.d.ts +301 -0
- package/dist/relay-quote.js +983 -0
- package/dist/route-steps.d.ts +138 -0
- package/dist/route-steps.js +305 -0
- package/dist/routing/amounts.d.ts +80 -0
- package/dist/routing/amounts.js +120 -0
- package/dist/routing/candidate-route.d.ts +43 -0
- package/dist/routing/candidate-route.js +45 -0
- package/dist/routing/candidate.d.ts +237 -0
- package/dist/routing/candidate.js +96 -0
- package/dist/routing/carriers/ask-answer.d.ts +58 -0
- package/dist/routing/carriers/ask-answer.js +1 -0
- package/dist/routing/carriers/omnibridge.d.ts +137 -0
- package/dist/routing/carriers/omnibridge.js +419 -0
- package/dist/routing/carriers/pulsex.d.ts +111 -0
- package/dist/routing/carriers/pulsex.js +404 -0
- package/dist/routing/carriers/wrap.d.ts +25 -0
- package/dist/routing/carriers/wrap.js +115 -0
- package/dist/routing/composed-route-quality.d.ts +103 -0
- package/dist/routing/composed-route-quality.js +108 -0
- package/dist/routing/entry-chain-anchor.d.ts +88 -0
- package/dist/routing/entry-chain-anchor.js +55 -0
- package/dist/routing/format.d.ts +31 -0
- package/dist/routing/format.js +58 -0
- package/dist/routing/index.d.ts +34 -0
- package/dist/routing/index.js +42 -0
- package/dist/routing/producers.d.ts +770 -0
- package/dist/routing/producers.js +1564 -0
- package/dist/routing/providers.d.ts +26 -0
- package/dist/routing/providers.js +38 -0
- package/dist/routing/route-data.d.ts +355 -0
- package/dist/routing/route-data.js +1 -0
- package/dist/routing/search/compose.d.ts +168 -0
- package/dist/routing/search/compose.js +98 -0
- package/dist/routing/search/graph.d.ts +639 -0
- package/dist/routing/search/graph.js +445 -0
- package/dist/routing/search/plan-route-data.d.ts +244 -0
- package/dist/routing/search/plan-route-data.js +767 -0
- package/dist/routing/search/score.d.ts +324 -0
- package/dist/routing/search/score.js +400 -0
- package/dist/routing/usd-value.d.ts +17 -0
- package/dist/routing/usd-value.js +25 -0
- package/dist/settings.d.ts +692 -0
- package/dist/settings.js +909 -0
- package/dist/ton-execution.d.ts +117 -0
- package/dist/ton-execution.js +247 -0
- package/dist/tron-execution.d.ts +146 -0
- package/dist/tron-execution.js +239 -0
- package/dist/types.d.ts +51 -0
- package/dist/types.js +1 -0
- package/package.json +203 -23
- package/src/chain-info.test.ts +0 -968
- package/src/chain-info.ts +0 -498
- package/src/chains.test.ts +0 -123
- package/src/chains.ts +0 -88
- package/src/config.test.ts +0 -679
- package/src/config.ts +0 -500
- package/src/fee-type.test.ts +0 -45
- package/src/fee-type.ts +0 -14
- package/src/image-links.test.ts +0 -160
- package/src/image-links.ts +0 -65
- package/src/index.ts +0 -8
- package/src/settings.test.ts +0 -2754
- package/src/settings.ts +0 -875
- package/src/types.ts +0 -48
- package/tsconfig.json +0 -17
- package/vitest.config.ts +0 -13
- /package/{src/abis.ts → dist/abis.js} +0 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { type DepositAddressChain } from './chain-names.js';
|
|
2
|
+
/**
|
|
3
|
+
* Sets the image root for the bridge
|
|
4
|
+
* @param root - the root
|
|
5
|
+
*/
|
|
6
|
+
export declare const setImageRoot: (root: string) => void;
|
|
7
|
+
/**
|
|
8
|
+
* Returns the image root for the bridge
|
|
9
|
+
* @returns the image root
|
|
10
|
+
*/
|
|
11
|
+
export declare const getImageRoot: () => string;
|
|
12
|
+
/** The minimal token info */
|
|
13
|
+
interface MinimalTokenInfo {
|
|
14
|
+
chainId: number;
|
|
15
|
+
address: string;
|
|
16
|
+
logoURI?: string | null;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Returns the list image for the given path
|
|
20
|
+
* @param path - the path
|
|
21
|
+
* @returns the list image
|
|
22
|
+
*/
|
|
23
|
+
export declare const list: (path: string) => string;
|
|
24
|
+
/**
|
|
25
|
+
* Returns the network image for the given chain id
|
|
26
|
+
* @param chainId - the chain id
|
|
27
|
+
* @returns the network image
|
|
28
|
+
*/
|
|
29
|
+
export declare const network: (chainId: number) => string;
|
|
30
|
+
/**
|
|
31
|
+
* gib.show's own key for a chain this package can only name by a LOCAL,
|
|
32
|
+
* INVENTED identifier — a pay-by-hand origin (see `depositAddressChainIds`)
|
|
33
|
+
* rather than a real chain id gib.show's numeric endpoint recognizes.
|
|
34
|
+
* `network(chainId)` 404s for one of these, and the browser draws that 404 as
|
|
35
|
+
* a broken image on every chain badge and route mark drawn through it.
|
|
36
|
+
*
|
|
37
|
+
* Every route producer that draws a chain badge for a token needs this, not
|
|
38
|
+
* only the deposit-address ones: a route can START on a deposit-address chain
|
|
39
|
+
* and cross through ordinary Ethereum-Virtual-Machine chains after, so the
|
|
40
|
+
* predicate has to run on every chain id a route touches, not only the one
|
|
41
|
+
* the reader picked. Kept beside `network` rather than in the client that also
|
|
42
|
+
* resolves Relay's pseudo chains (`@gibs/bridge-client/image`'s
|
|
43
|
+
* `chainLogoUrl`) because that client sits ABOVE this package — it imports
|
|
44
|
+
* FROM `bridge-sdk` — so this package importing back from it would be a
|
|
45
|
+
* cycle. `chainLogoUrl` still adds a Relay-icon fallback for chains gib.show
|
|
46
|
+
* does not carry at ALL (Eclipse, Hyperliquid); this table is only the
|
|
47
|
+
* chains gib.show DOES carry, under a key other than their numeric id.
|
|
48
|
+
*
|
|
49
|
+
* EXPORTED, and this is the ONLY place a pay-by-hand chain's gib.show key is
|
|
50
|
+
* declared. `@gibs/bridge-client`'s `image.ts` used to hard-code its own copy
|
|
51
|
+
* of the same `zcash → 'bip122-133'` entry; it now spreads this map into its
|
|
52
|
+
* own icon table instead, because the dependency runs one way — the client
|
|
53
|
+
* already imports from this package — so there was never a cycle stopping it.
|
|
54
|
+
*/
|
|
55
|
+
export declare const pseudoChainGibShowIdentifierByChain: Record<DepositAddressChain, string>;
|
|
56
|
+
/** {@link pseudoChainGibShowIdentifierByChain}, keyed by chain id for lookup. */
|
|
57
|
+
export declare const pseudoChainGibShowIdentifier: Readonly<Record<number, string>>;
|
|
58
|
+
/**
|
|
59
|
+
* The network image for a chain id, honouring a pseudo chain's own gib.show
|
|
60
|
+
* key when its numeric id is not one gib.show's `/image/<id>` endpoint knows.
|
|
61
|
+
*
|
|
62
|
+
* @param chainId - the chain id, a deposit-address chain's local identifier included
|
|
63
|
+
* @returns a working network/chain-badge image url
|
|
64
|
+
*/
|
|
65
|
+
export declare const networkOrPseudo: (chainId: number) => string;
|
|
66
|
+
/**
|
|
67
|
+
* Returns the image url for the given token info.
|
|
68
|
+
*
|
|
69
|
+
* The gas token is asked for by BOTH of its keys, because the service keys it
|
|
70
|
+
* two ways and each chain carries only one of them. `<chain>/<zero address>` is
|
|
71
|
+
* a dedicated picture — Ethereum's ether diamond, PulseChain's mark — and
|
|
72
|
+
* Binance Smart Chain has none, so asking for it there returns a 404 the browser
|
|
73
|
+
* draws as a broken image. The empty-address form `<chain>/` is the chain's own
|
|
74
|
+
* mark, which every chain has.
|
|
75
|
+
*
|
|
76
|
+
* The order is NOT interchangeable. The service serves the first source that
|
|
77
|
+
* resolves, so a chain with a dedicated picture keeps it; reversed, Ethereum
|
|
78
|
+
* would show the network logo where the ether logo belongs (the two are
|
|
79
|
+
* genuinely different files). The pair is for the gas token alone: pairing an
|
|
80
|
+
* ordinary contract address with the chain mark would hide a missing token logo
|
|
81
|
+
* behind the network's, showing the wrong token rather than an honest fallback.
|
|
82
|
+
*
|
|
83
|
+
* @param t - the token info
|
|
84
|
+
* @returns the image url
|
|
85
|
+
*/
|
|
86
|
+
export declare const image: (t: MinimalTokenInfo) => string;
|
|
87
|
+
/**
|
|
88
|
+
* {@link image}, but falling back to the token's own CHAIN mark rather than
|
|
89
|
+
* throwing or asking the service for a picture that was never going to exist,
|
|
90
|
+
* when the token carries no address a picture can be resolved from yet.
|
|
91
|
+
*
|
|
92
|
+
* WHY THIS EXISTS SEPARATELY FROM `image`. A route producer can reach the
|
|
93
|
+
* moment it draws a DELIVERED token's picture before that token's exact
|
|
94
|
+
* on-chain address is known — a not-yet-bridged token's `assetOutAddress` is
|
|
95
|
+
* documented to arrive `null` (see the repository's own "Not-Yet-Bridged
|
|
96
|
+
* Tokens" gotcha), and a deferred crossing's landing token is exactly this
|
|
97
|
+
* case: the reader has not yet signed the leg that would settle it. `image`
|
|
98
|
+
* either throws (`getAddress` refuses a malformed or empty string) or, for a
|
|
99
|
+
* caller that swallows the throw, silently draws nothing — the same "blank
|
|
100
|
+
* disc" defect the carrier marks were fixed for, one token lower. The chain's
|
|
101
|
+
* own mark is a real, recognisable picture that is honest about what is
|
|
102
|
+
* known: THIS chain, a token not yet resolved on it — the same trade
|
|
103
|
+
* `trackerView.ts`'s `depositAddressChainLogoFallback` already makes for a
|
|
104
|
+
* pay-by-hand ORIGIN with no address of its own.
|
|
105
|
+
*
|
|
106
|
+
* @param t - the token to draw
|
|
107
|
+
* @returns the token's own picture, or its chain's mark when the token's
|
|
108
|
+
* address cannot be resolved into one
|
|
109
|
+
*/
|
|
110
|
+
export declare const tokenImageOrChainFallback: (t: MinimalTokenInfo) => string;
|
|
111
|
+
/**
|
|
112
|
+
* Returns a url that will lookup all sources for the given array
|
|
113
|
+
* @param sources - the sources
|
|
114
|
+
* @returns the images
|
|
115
|
+
*/
|
|
116
|
+
export declare const images: (sources: string[]) => string;
|
|
117
|
+
export {};
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { getAddress, zeroAddress } from 'viem';
|
|
2
|
+
import { depositAddressChainIds } from './chain-names.js';
|
|
3
|
+
import { isNativeAsset } from './ecosystems.js';
|
|
4
|
+
let imageRoot = 'https://gib.show';
|
|
5
|
+
/**
|
|
6
|
+
* Sets the image root for the bridge
|
|
7
|
+
* @param root - the root
|
|
8
|
+
*/
|
|
9
|
+
export const setImageRoot = (root) => {
|
|
10
|
+
imageRoot = root;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Returns the image root for the bridge
|
|
14
|
+
* @returns the image root
|
|
15
|
+
*/
|
|
16
|
+
export const getImageRoot = () => imageRoot;
|
|
17
|
+
/**
|
|
18
|
+
* Returns the list image for the given path
|
|
19
|
+
* @param path - the path
|
|
20
|
+
* @returns the list image
|
|
21
|
+
*/
|
|
22
|
+
export const list = (path) => {
|
|
23
|
+
return `${imageRoot}/list${path}`;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Returns the network image for the given chain id
|
|
27
|
+
* @param chainId - the chain id
|
|
28
|
+
* @returns the network image
|
|
29
|
+
*/
|
|
30
|
+
export const network = (chainId) => `${imageRoot}/image/${Number(chainId)}`;
|
|
31
|
+
/**
|
|
32
|
+
* gib.show's own key for a chain this package can only name by a LOCAL,
|
|
33
|
+
* INVENTED identifier — a pay-by-hand origin (see `depositAddressChainIds`)
|
|
34
|
+
* rather than a real chain id gib.show's numeric endpoint recognizes.
|
|
35
|
+
* `network(chainId)` 404s for one of these, and the browser draws that 404 as
|
|
36
|
+
* a broken image on every chain badge and route mark drawn through it.
|
|
37
|
+
*
|
|
38
|
+
* Every route producer that draws a chain badge for a token needs this, not
|
|
39
|
+
* only the deposit-address ones: a route can START on a deposit-address chain
|
|
40
|
+
* and cross through ordinary Ethereum-Virtual-Machine chains after, so the
|
|
41
|
+
* predicate has to run on every chain id a route touches, not only the one
|
|
42
|
+
* the reader picked. Kept beside `network` rather than in the client that also
|
|
43
|
+
* resolves Relay's pseudo chains (`@gibs/bridge-client/image`'s
|
|
44
|
+
* `chainLogoUrl`) because that client sits ABOVE this package — it imports
|
|
45
|
+
* FROM `bridge-sdk` — so this package importing back from it would be a
|
|
46
|
+
* cycle. `chainLogoUrl` still adds a Relay-icon fallback for chains gib.show
|
|
47
|
+
* does not carry at ALL (Eclipse, Hyperliquid); this table is only the
|
|
48
|
+
* chains gib.show DOES carry, under a key other than their numeric id.
|
|
49
|
+
*
|
|
50
|
+
* EXPORTED, and this is the ONLY place a pay-by-hand chain's gib.show key is
|
|
51
|
+
* declared. `@gibs/bridge-client`'s `image.ts` used to hard-code its own copy
|
|
52
|
+
* of the same `zcash → 'bip122-133'` entry; it now spreads this map into its
|
|
53
|
+
* own icon table instead, because the dependency runs one way — the client
|
|
54
|
+
* already imports from this package — so there was never a cycle stopping it.
|
|
55
|
+
*/
|
|
56
|
+
export const pseudoChainGibShowIdentifierByChain = {
|
|
57
|
+
zcash: 'bip122-133',
|
|
58
|
+
};
|
|
59
|
+
/** {@link pseudoChainGibShowIdentifierByChain}, keyed by chain id for lookup. */
|
|
60
|
+
export const pseudoChainGibShowIdentifier = Object.fromEntries(Object.keys(depositAddressChainIds).map((chain) => [
|
|
61
|
+
depositAddressChainIds[chain],
|
|
62
|
+
pseudoChainGibShowIdentifierByChain[chain],
|
|
63
|
+
]));
|
|
64
|
+
/**
|
|
65
|
+
* The network image for a chain id, honouring a pseudo chain's own gib.show
|
|
66
|
+
* key when its numeric id is not one gib.show's `/image/<id>` endpoint knows.
|
|
67
|
+
*
|
|
68
|
+
* @param chainId - the chain id, a deposit-address chain's local identifier included
|
|
69
|
+
* @returns a working network/chain-badge image url
|
|
70
|
+
*/
|
|
71
|
+
export const networkOrPseudo = (chainId) => {
|
|
72
|
+
const identifier = pseudoChainGibShowIdentifier[chainId];
|
|
73
|
+
return identifier !== undefined ? `${imageRoot}/image/${identifier}` : network(chainId);
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* Returns the image url for the given token info.
|
|
77
|
+
*
|
|
78
|
+
* The gas token is asked for by BOTH of its keys, because the service keys it
|
|
79
|
+
* two ways and each chain carries only one of them. `<chain>/<zero address>` is
|
|
80
|
+
* a dedicated picture — Ethereum's ether diamond, PulseChain's mark — and
|
|
81
|
+
* Binance Smart Chain has none, so asking for it there returns a 404 the browser
|
|
82
|
+
* draws as a broken image. The empty-address form `<chain>/` is the chain's own
|
|
83
|
+
* mark, which every chain has.
|
|
84
|
+
*
|
|
85
|
+
* The order is NOT interchangeable. The service serves the first source that
|
|
86
|
+
* resolves, so a chain with a dedicated picture keeps it; reversed, Ethereum
|
|
87
|
+
* would show the network logo where the ether logo belongs (the two are
|
|
88
|
+
* genuinely different files). The pair is for the gas token alone: pairing an
|
|
89
|
+
* ordinary contract address with the chain mark would hide a missing token logo
|
|
90
|
+
* behind the network's, showing the wrong token rather than an honest fallback.
|
|
91
|
+
*
|
|
92
|
+
* @param t - the token info
|
|
93
|
+
* @returns the image url
|
|
94
|
+
*/
|
|
95
|
+
export const image = (t) => {
|
|
96
|
+
if (t.logoURI)
|
|
97
|
+
return t.logoURI;
|
|
98
|
+
if (isNativeAsset(t.address, 'evm')) {
|
|
99
|
+
return images([`${Number(t.chainId)}/${zeroAddress}`, `${Number(t.chainId)}/`]);
|
|
100
|
+
}
|
|
101
|
+
return `${network(t.chainId)}/${getAddress(t.address)}`;
|
|
102
|
+
};
|
|
103
|
+
/**
|
|
104
|
+
* Whether `address` is a real Ethereum-Virtual-Machine address {@link image}
|
|
105
|
+
* can ask the service about — the zero address included, since that is
|
|
106
|
+
* {@link isNativeAsset}'s own case and {@link image} handles it without
|
|
107
|
+
* `getAddress` ever running.
|
|
108
|
+
*
|
|
109
|
+
* @param address - the address to check
|
|
110
|
+
* @returns true when `getAddress` can checksum it without throwing
|
|
111
|
+
*/
|
|
112
|
+
const isResolvableEvmAddress = (address) => /^0x[0-9a-fA-F]{40}$/.test(address);
|
|
113
|
+
/**
|
|
114
|
+
* {@link image}, but falling back to the token's own CHAIN mark rather than
|
|
115
|
+
* throwing or asking the service for a picture that was never going to exist,
|
|
116
|
+
* when the token carries no address a picture can be resolved from yet.
|
|
117
|
+
*
|
|
118
|
+
* WHY THIS EXISTS SEPARATELY FROM `image`. A route producer can reach the
|
|
119
|
+
* moment it draws a DELIVERED token's picture before that token's exact
|
|
120
|
+
* on-chain address is known — a not-yet-bridged token's `assetOutAddress` is
|
|
121
|
+
* documented to arrive `null` (see the repository's own "Not-Yet-Bridged
|
|
122
|
+
* Tokens" gotcha), and a deferred crossing's landing token is exactly this
|
|
123
|
+
* case: the reader has not yet signed the leg that would settle it. `image`
|
|
124
|
+
* either throws (`getAddress` refuses a malformed or empty string) or, for a
|
|
125
|
+
* caller that swallows the throw, silently draws nothing — the same "blank
|
|
126
|
+
* disc" defect the carrier marks were fixed for, one token lower. The chain's
|
|
127
|
+
* own mark is a real, recognisable picture that is honest about what is
|
|
128
|
+
* known: THIS chain, a token not yet resolved on it — the same trade
|
|
129
|
+
* `trackerView.ts`'s `depositAddressChainLogoFallback` already makes for a
|
|
130
|
+
* pay-by-hand ORIGIN with no address of its own.
|
|
131
|
+
*
|
|
132
|
+
* @param t - the token to draw
|
|
133
|
+
* @returns the token's own picture, or its chain's mark when the token's
|
|
134
|
+
* address cannot be resolved into one
|
|
135
|
+
*/
|
|
136
|
+
export const tokenImageOrChainFallback = (t) => isResolvableEvmAddress(t.address) ? image(t) : networkOrPseudo(t.chainId);
|
|
137
|
+
/**
|
|
138
|
+
* Returns a url that will lookup all sources for the given array
|
|
139
|
+
* @param sources - the sources
|
|
140
|
+
* @returns the images
|
|
141
|
+
*/
|
|
142
|
+
export const images = (sources) => `${imageRoot}/image/?${sources.map((s) => `i=${s}`).join('&')}`;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export * from './abis.js';
|
|
2
|
+
export * from './bridge-limits.js';
|
|
3
|
+
export * from './chain-info.js';
|
|
4
|
+
export * from './chains.js';
|
|
5
|
+
export * from './config.js';
|
|
6
|
+
export * from './consolidated-quote.js';
|
|
7
|
+
export * from './relay-quote.js';
|
|
8
|
+
export * from './relay-currencies.js';
|
|
9
|
+
export * from './destination-calldata.js';
|
|
10
|
+
export * from './ecosystems.js';
|
|
11
|
+
export * from './fee-type.js';
|
|
12
|
+
export * from './image-links.js';
|
|
13
|
+
export * from './lifi-execution-guard.js';
|
|
14
|
+
export * from './origin-deposit.js';
|
|
15
|
+
export * from './providers.js';
|
|
16
|
+
export * from './referral.js';
|
|
17
|
+
export * from './route-steps.js';
|
|
18
|
+
export * from './routing/index.js';
|
|
19
|
+
export * from './settings.js';
|
|
20
|
+
export * from './types.js';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export * from './abis.js';
|
|
2
|
+
export * from './bridge-limits.js';
|
|
3
|
+
export * from './chain-info.js';
|
|
4
|
+
export * from './chains.js';
|
|
5
|
+
export * from './config.js';
|
|
6
|
+
export * from './consolidated-quote.js';
|
|
7
|
+
export * from './relay-quote.js';
|
|
8
|
+
export * from './relay-currencies.js';
|
|
9
|
+
export * from './destination-calldata.js';
|
|
10
|
+
export * from './ecosystems.js';
|
|
11
|
+
export * from './fee-type.js';
|
|
12
|
+
export * from './image-links.js';
|
|
13
|
+
export * from './lifi-execution-guard.js';
|
|
14
|
+
export * from './origin-deposit.js';
|
|
15
|
+
export * from './providers.js';
|
|
16
|
+
export * from './referral.js';
|
|
17
|
+
export * from './route-steps.js';
|
|
18
|
+
export * from './routing/index.js';
|
|
19
|
+
export * from './settings.js';
|
|
20
|
+
export * from './types.js';
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { type Hex } from 'viem';
|
|
2
|
+
/**
|
|
3
|
+
* Verifies a LI.FI EVM execution transaction before a wallet ever signs it.
|
|
4
|
+
*
|
|
5
|
+
* WHY THIS EXISTS. `lifiApi.quote` and `lifiApi.contractCallsQuote` are fetched
|
|
6
|
+
* through a configurable base URL — today `lifi.gibs.finance`, a server-side
|
|
7
|
+
* proxy; the interface may point at a different host in the future. Whichever
|
|
8
|
+
* host answers, this codebase used to sign whatever `transactionRequest` came
|
|
9
|
+
* back after checking only that `to` and `data` were hexadecimal strings (see
|
|
10
|
+
* `lifiEvmDeposit` in `consolidated-quote.ts`). A COMPROMISED PROXY could
|
|
11
|
+
* return ANY `to`/`data`/`value` and a connected wallet would sign it,
|
|
12
|
+
* moving the reader's funds wherever the proxy chose.
|
|
13
|
+
*
|
|
14
|
+
* WHAT THIS MODULE PROVES INSTEAD, before signing:
|
|
15
|
+
*
|
|
16
|
+
* 1. `to` (and, when present, `estimate.approvalAddress`) is LI.FI's own
|
|
17
|
+
* Diamond entryway contract for the chain the transaction runs on — a
|
|
18
|
+
* fixed table, not something the response gets to assert about itself.
|
|
19
|
+
* See {@link lifiDiamondAddressByChainId}.
|
|
20
|
+
* 2. The calldata's selector is one of a small, explicitly verified set of
|
|
21
|
+
* LI.FI facet functions whose ABI this module carries in full. An unknown
|
|
22
|
+
* selector is refused rather than guessed at.
|
|
23
|
+
* 3. The decoded `BridgeData` and leading `SwapData` entry agree with what
|
|
24
|
+
* THIS APPLICATION asked for — not with other fields of the same,
|
|
25
|
+
* potentially compromised, response. See {@link LifiExecutionExpectation}.
|
|
26
|
+
* 4. `transactionRequest.value` equals exactly the native currency the
|
|
27
|
+
* decoded calldata implies (the amount being deposited, when that amount
|
|
28
|
+
* is native, plus any protocol messaging fee the tool's own data
|
|
29
|
+
* declares) — never more, never less.
|
|
30
|
+
*
|
|
31
|
+
* WHERE THE FIELD SEMANTICS CAME FROM. Every fact this module relies on —
|
|
32
|
+
* which struct field means what, and how the three verified facet functions
|
|
33
|
+
* actually populate `BridgeData` and `SwapData` — was read from REAL
|
|
34
|
+
* responses captured live from `https://li.quest`, decoded with this exact
|
|
35
|
+
* machinery, and cross-checked against the deployed contracts' Solidity
|
|
36
|
+
* source (`lifinance/contracts`, commit `025989955bb373739737ee78ddff01620638ae3b`,
|
|
37
|
+
* 2026-09-23). Two assumptions a first reading of LI.FI's own field
|
|
38
|
+
* descriptions would suggest turned out to be wrong, and are recorded here so
|
|
39
|
+
* nobody reintroduces them:
|
|
40
|
+
*
|
|
41
|
+
* - `BridgeData.receiver` is NOT "the final recipient" in general. For the
|
|
42
|
+
* contract-calls endpoint (`hasDestinationCall: true`) it decoded to the
|
|
43
|
+
* REQUEST'S `toFallbackAddress` — the address that receives the bridged
|
|
44
|
+
* asset if the destination call reverts — not the destination call's own
|
|
45
|
+
* contract or the reader's recipient. Only for the plain endpoint
|
|
46
|
+
* (`hasDestinationCall: false`) does it equal the recipient (`toAddress`).
|
|
47
|
+
* Verified against three independently captured quotes; see the fixtures
|
|
48
|
+
* this module's test file reads.
|
|
49
|
+
* - `BridgeData.minAmount` is NOT the destination-side guaranteed amount for
|
|
50
|
+
* any of the three verified tools. It is the amount of `sendingAssetId`
|
|
51
|
+
* pulled from the depositor on the ORIGIN chain (`LibAsset.depositAsset`
|
|
52
|
+
* in every facet's Solidity), reassigned at runtime to the real swap
|
|
53
|
+
* output when `hasSourceSwaps` is true — a fact this module's calldata
|
|
54
|
+
* never carries. The genuine destination-side guarantee lives in each
|
|
55
|
+
* tool's own trailing struct (`AcrossV4Data.outputAmount`,
|
|
56
|
+
* `StargateData.sendParams.minAmountLD`) and is read from there instead.
|
|
57
|
+
* LayerSwap's own struct carries no on-chain amount field at all — its
|
|
58
|
+
* guarantee is an off-chain, backend-signed attestation — so this module
|
|
59
|
+
* cannot verify a destination minimum for it and refuses to try; see
|
|
60
|
+
* {@link DecodedLifiFacetCall.destinationMinimum}.
|
|
61
|
+
*
|
|
62
|
+
* SCOPE, DELIBERATELY NARROW. Only the exact facet-function shapes seen in a
|
|
63
|
+
* REAL captured LI.FI response are decoded; every other selector refuses.
|
|
64
|
+
* Adding a new tool means capturing a fixture for it first — see
|
|
65
|
+
* `packages/bridge-sdk/src/__fixtures__/lifi/README.md` — and extending
|
|
66
|
+
* {@link lifiFacetDecoders} from that fixture, never from documentation
|
|
67
|
+
* alone (per the hand-built-quotes-hide-parser-gaps lesson: a decoder written
|
|
68
|
+
* from a guess passes its own hand-built test and nothing else).
|
|
69
|
+
*/
|
|
70
|
+
/**
|
|
71
|
+
* Every reason this module can refuse a LI.FI execution transaction.
|
|
72
|
+
*
|
|
73
|
+
* Each maps to one property of the response this module distrusts by
|
|
74
|
+
* default: `unknown-chain` and `router-mismatch` distrust `to`;
|
|
75
|
+
* `approval-address-mismatch` distrusts `estimate.approvalAddress`;
|
|
76
|
+
* `unknown-selector` and `calldata-undecodable` distrust `data`'s shape;
|
|
77
|
+
* `receiver-mismatch`, `destination-chain-mismatch`, `sending-asset-mismatch`,
|
|
78
|
+
* `destination-call-flag-mismatch` and `minimum-amount-below-requested`
|
|
79
|
+
* distrust `data`'s DECODED fields against what this application asked for;
|
|
80
|
+
* `native-value-mismatch` distrusts `value`. `missing-request-context` is
|
|
81
|
+
* different in kind: it means the CALLER never supplied what this
|
|
82
|
+
* application expected, so none of the above could even be checked — see
|
|
83
|
+
* `parseLifiContractCallsQuote` and `parseLifiQuote` in `consolidated-quote.ts`.
|
|
84
|
+
*/
|
|
85
|
+
export type LifiExecutionRefusalReason = 'unknown-chain' | 'router-mismatch' | 'approval-address-mismatch' | 'unknown-selector' | 'calldata-undecodable' | 'receiver-mismatch' | 'destination-chain-mismatch' | 'sending-asset-mismatch' | 'destination-call-flag-mismatch' | 'minimum-amount-below-requested' | 'native-value-mismatch' | 'missing-request-context';
|
|
86
|
+
/** Why a LI.FI execution transaction was refused before signing. */
|
|
87
|
+
export type LifiExecutionRefusal = {
|
|
88
|
+
readonly reason: LifiExecutionRefusalReason;
|
|
89
|
+
/** A short, specific explanation naming the values that disagreed. */
|
|
90
|
+
readonly detail: string;
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* Thrown by {@link verifyLifiEvmExecution} instead of returning a deposit a
|
|
94
|
+
* wallet could sign.
|
|
95
|
+
*
|
|
96
|
+
* NAMED AND TYPED SO A REFUSAL IS NEVER A SILENT DROP. Every caller that
|
|
97
|
+
* catches this can read `refusal.reason` and show, or log, exactly which
|
|
98
|
+
* check failed — the same discipline `@gibs/quotes`'s `ProviderQuoteError`
|
|
99
|
+
* applies to a provider declining a quote, applied here to a provider's
|
|
100
|
+
* ANSWER disagreeing with itself.
|
|
101
|
+
*/
|
|
102
|
+
export declare class LifiExecutionRefusedError extends Error {
|
|
103
|
+
readonly refusal: LifiExecutionRefusal;
|
|
104
|
+
constructor(refusal: LifiExecutionRefusal);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* LI.FI's Diamond entryway contract address, by chain id.
|
|
108
|
+
*
|
|
109
|
+
* SOURCE. `lifinance/contracts` (https://github.com/lifinance/contracts),
|
|
110
|
+
* commit `025989955bb373739737ee78ddff01620638ae3b` (2026-09-23): the
|
|
111
|
+
* `LiFiDiamond` address in `deployments/<network>.json`, matched to its
|
|
112
|
+
* chain id in `config/networks.json`, for every network whose `status` is
|
|
113
|
+
* `"active"` and `"type"` is `"mainnet"`. LI.FI's own documentation
|
|
114
|
+
* (https://docs.li.fi/introduction/lifi-architecture/smart-contract-addresses)
|
|
115
|
+
* states the address is `0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE` "on most
|
|
116
|
+
* supported networks" but differs on some — confirmed here directly against
|
|
117
|
+
* the deployment records rather than assumed: 39 of the 65 active mainnet
|
|
118
|
+
* networks use a DIFFERENT address, almost all of them newer or lower-volume
|
|
119
|
+
* chains (0G, Abstract, ApeChain, Arbitrum Nova, Berachain, Flare, zkSync
|
|
120
|
+
* Era, and more).
|
|
121
|
+
*
|
|
122
|
+
* DELIBERATELY A FIXED, BAKED-IN TABLE, NEVER A LIVE LOOKUP. LI.FI's own
|
|
123
|
+
* `/v1/chains` endpoint carries a `diamondAddress` per chain, and this
|
|
124
|
+
* codebase already fetches it for other purposes — but that endpoint is
|
|
125
|
+
* reached through the SAME configurable, potentially-compromised host this
|
|
126
|
+
* module exists to distrust. Trusting it here would make the whole guard
|
|
127
|
+
* circular: a compromised proxy could simply report its own malicious
|
|
128
|
+
* address as the "correct" one. This table is real code, reviewed and
|
|
129
|
+
* shipped with the application, and can only change through a new release.
|
|
130
|
+
*
|
|
131
|
+
* UNKNOWN CHAIN, UNKNOWN ADDRESS. A chain id absent from this table refuses
|
|
132
|
+
* rather than falling back to the common address — LI.FI adds networks
|
|
133
|
+
* continuously, and assuming a newly-added chain shares the common address
|
|
134
|
+
* would be exactly the kind of guess this module exists to avoid making.
|
|
135
|
+
*/
|
|
136
|
+
export declare const lifiDiamondAddressByChainId: ReadonlyMap<number, Hex>;
|
|
137
|
+
/** LI.FI's `ILiFi.BridgeData` struct — identical across every facet function. */
|
|
138
|
+
export type LifiBridgeData = {
|
|
139
|
+
readonly transactionId: Hex;
|
|
140
|
+
readonly bridge: string;
|
|
141
|
+
readonly integrator: string;
|
|
142
|
+
readonly referrer: Hex;
|
|
143
|
+
readonly sendingAssetId: Hex;
|
|
144
|
+
readonly receiver: Hex;
|
|
145
|
+
readonly minAmount: bigint;
|
|
146
|
+
readonly destinationChainId: bigint;
|
|
147
|
+
readonly hasSourceSwaps: boolean;
|
|
148
|
+
readonly hasDestinationCall: boolean;
|
|
149
|
+
};
|
|
150
|
+
/**
|
|
151
|
+
* What THIS APPLICATION asked LI.FI for, independent of anything the
|
|
152
|
+
* response itself claims — the only thing a decoded transaction is allowed
|
|
153
|
+
* to be checked against.
|
|
154
|
+
*/
|
|
155
|
+
export type LifiExecutionExpectation = {
|
|
156
|
+
/**
|
|
157
|
+
* Where the bridged asset lands if the route needs no destination call
|
|
158
|
+
* (the plain endpoint's recipient), or where it lands if the destination
|
|
159
|
+
* call reverts (the contract-calls endpoint's fallback address) — see the
|
|
160
|
+
* `BridgeData.receiver` note at the top of this file for why these two are
|
|
161
|
+
* NOT the same field despite the shared name.
|
|
162
|
+
*/
|
|
163
|
+
readonly receiver: Hex;
|
|
164
|
+
/** The chain the entry call (or the plain delivery) must land on. */
|
|
165
|
+
readonly destinationChainId: number;
|
|
166
|
+
/** The token this application is paying with on the origin chain. */
|
|
167
|
+
readonly sendingAssetId: Hex;
|
|
168
|
+
/** Whether this application attached an omnibridge entry call. */
|
|
169
|
+
readonly hasDestinationCall: boolean;
|
|
170
|
+
/**
|
|
171
|
+
* The guaranteed minimum this application asked LI.FI to deliver, or
|
|
172
|
+
* `null` for the plain (forward-solved) endpoint, which names no such
|
|
173
|
+
* minimum — the delivered amount is read back from the response instead
|
|
174
|
+
* of constrained by the request. See `ConsolidatedQuote.toAmount`.
|
|
175
|
+
*/
|
|
176
|
+
readonly minimumAmount: bigint | null;
|
|
177
|
+
};
|
|
178
|
+
/** The transaction fields {@link verifyLifiEvmExecution} reads off the raw response. */
|
|
179
|
+
export type LifiExecutionTransactionRequest = {
|
|
180
|
+
readonly to: Hex;
|
|
181
|
+
readonly data: Hex;
|
|
182
|
+
readonly value: bigint;
|
|
183
|
+
readonly chainId: number;
|
|
184
|
+
};
|
|
185
|
+
/**
|
|
186
|
+
* Verifies a LI.FI EVM execution transaction against what this application
|
|
187
|
+
* asked for, throwing {@link LifiExecutionRefusedError} on any disagreement.
|
|
188
|
+
* Returns normally — carrying nothing, since the caller already holds the
|
|
189
|
+
* transaction it validated — when every check passes.
|
|
190
|
+
*
|
|
191
|
+
* See this module's top-of-file doc comment for what is checked and why.
|
|
192
|
+
*
|
|
193
|
+
* @param transactionRequest - the parsed `to`/`data`/`value`/`chainId` this
|
|
194
|
+
* application is about to hand to a wallet
|
|
195
|
+
* @param approvalAddress - `estimate.approvalAddress` from the same
|
|
196
|
+
* response, or `null` when the route needs no token approval
|
|
197
|
+
* @param expectation - what this application actually asked for
|
|
198
|
+
*/
|
|
199
|
+
export declare const verifyLifiEvmExecution: (transactionRequest: LifiExecutionTransactionRequest, approvalAddress: Hex | null, expectation: LifiExecutionExpectation) => void;
|