@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/README.md
CHANGED
|
@@ -441,6 +441,39 @@ if (plan.kind === 'refused') throw new Error(plan.refusal.reason);
|
|
|
441
441
|
asked for your wallet, in `sections[i].aggregator`. The candidate's own quote
|
|
442
442
|
priced the route on screen and is never signed.
|
|
443
443
|
|
|
444
|
+
### Counting signatures, approvals included
|
|
445
|
+
|
|
446
|
+
`routeSignatureCount(route)` counts sections only, so a USDC route reads 1 and
|
|
447
|
+
then asks for two prompts. It leaves out approvals. Use
|
|
448
|
+
`routeSignatureCountForAccount` for the number the wallet will really ask for:
|
|
449
|
+
|
|
450
|
+
```ts
|
|
451
|
+
import {
|
|
452
|
+
type AllowanceReader,
|
|
453
|
+
type ResolveNodeToken,
|
|
454
|
+
type RouteCandidate,
|
|
455
|
+
type SectionExecutionInputs,
|
|
456
|
+
routeSignatureCountForAccount,
|
|
457
|
+
} from '@gibs/bridge-sdk';
|
|
458
|
+
import type { Hex } from 'viem';
|
|
459
|
+
|
|
460
|
+
declare const candidate: RouteCandidate;
|
|
461
|
+
declare const account: Hex;
|
|
462
|
+
declare const readAllowance: AllowanceReader;
|
|
463
|
+
declare const resolveToken: ResolveNodeToken;
|
|
464
|
+
declare const sections: SectionExecutionInputs[];
|
|
465
|
+
|
|
466
|
+
const { signatures, approvals, total } = await routeSignatureCountForAccount({
|
|
467
|
+
candidate, account, readAllowance, resolveToken, sections,
|
|
468
|
+
});
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
It takes the inputs `planCandidateExecution` takes and counts the plan, so it
|
|
472
|
+
uses the same allowance rule and the same spender (mediator, swap router, or
|
|
473
|
+
aggregator address). A native input and a covered allowance add no approval. A
|
|
474
|
+
short, non-zero allowance counts two approvals (reset, then approve). It throws
|
|
475
|
+
when a section cannot be planned.
|
|
476
|
+
|
|
444
477
|
## Overriding swap routers
|
|
445
478
|
|
|
446
479
|
The package swaps on PulseX V1 and V2 on PulseChain by default. You can swap on
|
package/dist/abis.js
CHANGED
package/dist/bridge-limits.js
CHANGED
|
@@ -1,25 +1,8 @@
|
|
|
1
1
|
import { parseAbi } from 'viem';
|
|
2
|
-
/**
|
|
3
|
-
* Exported so a batched reader (`routing/carriers/omnibridge.ts`'s `prepare`)
|
|
4
|
-
* can multicall the same two functions across many tokens in one call rather
|
|
5
|
-
* than duplicating this ABI.
|
|
6
|
-
*/
|
|
7
2
|
export const entryLimitsAbi = parseAbi([
|
|
8
3
|
'function minPerTx(address token) external view returns(uint256)',
|
|
9
4
|
'function maxAvailablePerTx(address token) external view returns(uint256)',
|
|
10
5
|
]);
|
|
11
|
-
/**
|
|
12
|
-
* Reads the bounds the entry mediator will enforce on this exact call.
|
|
13
|
-
*
|
|
14
|
-
* IT TAKES THE CALL, NOT A MEDIATOR AND A TOKEN. The two travel together on the
|
|
15
|
-
* destination call precisely so a caller cannot pair one route's mediator with
|
|
16
|
-
* another route's token and get a plausible number back — the reads would
|
|
17
|
-
* succeed and the answer would be about a transfer nobody is making.
|
|
18
|
-
*
|
|
19
|
-
* @param destinationCall - the entry call, or null when none could be built
|
|
20
|
-
* @param entryChainClient - a client on the chain the funds leave
|
|
21
|
-
* @returns the two bounds, or null when there is no call to measure
|
|
22
|
-
*/
|
|
23
6
|
export const bridgeEntryLimits = async ({ destinationCall, entryChainClient, }) => {
|
|
24
7
|
if (!destinationCall) {
|
|
25
8
|
return null;
|
|
@@ -41,28 +24,7 @@ export const bridgeEntryLimits = async ({ destinationCall, entryChainClient, })
|
|
|
41
24
|
]);
|
|
42
25
|
return { minimumPerTransaction, availablePerTransaction };
|
|
43
26
|
};
|
|
44
|
-
/**
|
|
45
|
-
* Decides whether an amount can enter the bridge.
|
|
46
|
-
*
|
|
47
|
-
* WHY THIS IS WORTH CHECKING BEFORE A ROUTE IS OFFERED: on a consolidated
|
|
48
|
-
* route the entry call is made by an aggregator's executor, not by the user.
|
|
49
|
-
* When the mediator rejects the amount the executor's call reverts, the
|
|
50
|
-
* aggregator has already delivered the funds, and they stop at the fallback
|
|
51
|
-
* address on the entry chain. The user is left holding an entry-chain token
|
|
52
|
-
* and a second transfer to make. Refusing the quote costs them nothing.
|
|
53
|
-
*
|
|
54
|
-
* The bounds are inclusive: the mediator accepts an amount equal to either.
|
|
55
|
-
*
|
|
56
|
-
* @param amount - the transfer, in the token's base units
|
|
57
|
-
* @param limits - the bounds from {@link bridgeEntryLimits}, or null when they
|
|
58
|
-
* could not be read
|
|
59
|
-
* @returns a verdict naming the bound that was missed
|
|
60
|
-
*/
|
|
61
27
|
export const checkEntryAmount = ({ amount, limits, }) => {
|
|
62
|
-
// An unread limit is not a failed one. A network hiccup must not block a
|
|
63
|
-
// route that the mediator would accept — the transaction still gets the
|
|
64
|
-
// mediator's own answer, and this guard exists to save the user a wasted
|
|
65
|
-
// crossing, not to be the only thing standing between them and a revert.
|
|
66
28
|
if (!limits) {
|
|
67
29
|
return { fits: true };
|
|
68
30
|
}
|
package/dist/chain-info.js
CHANGED
|
@@ -4,34 +4,8 @@ import { encodeFunctionData, getContract, multicall3Abi, zeroAddress, } from 'vi
|
|
|
4
4
|
import * as abis from './abis.js';
|
|
5
5
|
import { chainsMetadata } from './chains.js';
|
|
6
6
|
import { nativeAssetOut, pathway, toChain, uniV2Routers, } from './config.js';
|
|
7
|
-
/** Cache key for the links memoize: one entry per (chain, bridge, token) triple. */
|
|
8
7
|
const linksCacheKey = ({ chainId, target, address, }) => `${chainId}-${target}-${address}`.toLowerCase();
|
|
9
|
-
/**
|
|
10
|
-
* Whether a {@link links} answer says the token has no mapping on this bridge
|
|
11
|
-
* yet. That answer is temporary: the first transfer of the token creates the
|
|
12
|
-
* mapping, so it must not be cached.
|
|
13
|
-
* @param pair - the bridged and native addresses the mediator returned
|
|
14
|
-
* @returns true when both are the zero address
|
|
15
|
-
*/
|
|
16
8
|
const isUnmappedAnswer = ([bridged, native]) => bridged === zeroAddress && native === zeroAddress;
|
|
17
|
-
/**
|
|
18
|
-
* Returns the bridged token address and native token address that a mediator
|
|
19
|
-
* holds for one token.
|
|
20
|
-
*
|
|
21
|
-
* A non-zero answer is cached for the life of the process: a mediator never
|
|
22
|
-
* changes a mapping once the first transfer creates it. A failed read, and a
|
|
23
|
-
* `[zero, zero]` answer (the token is not bridged yet), are not cached, so the
|
|
24
|
-
* next call reads the chain again. Call {@link clearChainInfoCaches} to drop
|
|
25
|
-
* every cached answer.
|
|
26
|
-
*
|
|
27
|
-
* @param inputs.chainId - the chain id being targeted
|
|
28
|
-
* @param inputs.target - the mediator to ask
|
|
29
|
-
* @param inputs.address - the token address
|
|
30
|
-
* @param inputs.client - a client for that chain
|
|
31
|
-
* @returns the bridged token address and native token address
|
|
32
|
-
*/
|
|
33
|
-
// The body reaches for `links.cache` to evict an answer, so the cache surface
|
|
34
|
-
// is spelled out to the extent this file uses it.
|
|
35
9
|
export const links = memoizeByKey(async (inputs) => {
|
|
36
10
|
const { chainId, target, address, client } = inputs;
|
|
37
11
|
const evict = () => links.cache.delete(linksCacheKey(inputs));
|
|
@@ -45,34 +19,17 @@ export const links = memoizeByKey(async (inputs) => {
|
|
|
45
19
|
{ functionName: 'nativeTokenAddress', args: [address] },
|
|
46
20
|
],
|
|
47
21
|
}).catch((error) => {
|
|
48
|
-
// a transient read failure must not poison the cache for the session
|
|
49
22
|
evict();
|
|
50
23
|
throw error;
|
|
51
24
|
});
|
|
52
25
|
if (isUnmappedAnswer(pair)) {
|
|
53
|
-
// the token may be bridged a minute from now; ask again next time
|
|
54
26
|
evict();
|
|
55
27
|
}
|
|
56
28
|
return pair;
|
|
57
29
|
}, linksCacheKey);
|
|
58
|
-
/**
|
|
59
|
-
* Drops every answer this module has cached, so the next read goes to the chain.
|
|
60
|
-
*
|
|
61
|
-
* Use it after a token's first transfer, in a long-running process that wants
|
|
62
|
-
* a fresh view, or between tests.
|
|
63
|
-
*/
|
|
64
30
|
export const clearChainInfoCaches = () => {
|
|
65
31
|
links.cache.clear();
|
|
66
32
|
};
|
|
67
|
-
/**
|
|
68
|
-
* Returns the token bridge info for the given bridge key, asset in, is prod, from chain client, and to chain client
|
|
69
|
-
* @param bridgeKey - the bridge key
|
|
70
|
-
* @param assetIn - the asset in
|
|
71
|
-
* @param isProd - whether to use the production pathway
|
|
72
|
-
* @param fromChainClient - the from chain client
|
|
73
|
-
* @param toChainClient - the to chain client
|
|
74
|
-
* @returns the token bridge info
|
|
75
|
-
*/
|
|
76
33
|
export const tokenBridgeInfo = async ({ bridgeKey, assetIn, isProd, fromChainClient, toChainClient, }) => {
|
|
77
34
|
const bridgePathway = pathway(bridgeKey, isProd, assetIn?.address);
|
|
78
35
|
if (!assetIn || !bridgePathway) {
|
|
@@ -140,7 +97,6 @@ export const tokenBridgeInfo = async ({ bridgeKey, assetIn, isProd, fromChainCli
|
|
|
140
97
|
},
|
|
141
98
|
};
|
|
142
99
|
}
|
|
143
|
-
// the token has not been bridged yet
|
|
144
100
|
return {
|
|
145
101
|
originationChainId: toChain,
|
|
146
102
|
assetInAddress: assetInAddress,
|
|
@@ -160,23 +116,11 @@ export const tokenBridgeInfo = async ({ bridgeKey, assetIn, isProd, fromChainCli
|
|
|
160
116
|
}),
|
|
161
117
|
};
|
|
162
118
|
};
|
|
163
|
-
/**
|
|
164
|
-
* Check the prices that each router offers for the given paths
|
|
165
|
-
* @param assetInAddress the address of the asset going into the bridge
|
|
166
|
-
* @param oneTokenInt the number of tokens to push into the bridge (before fees)
|
|
167
|
-
* @param chain the chain of the asset going into the bridge
|
|
168
|
-
* @param bridgeKey the bridge key
|
|
169
|
-
* @param blockNumber the block number to use for the price
|
|
170
|
-
* @param paths the paths to check
|
|
171
|
-
* @returns the prices as bigint for each path, hex whenever the price is not available
|
|
172
|
-
*/
|
|
173
119
|
const readAmountOut = ({ amountIn, chain, paths, client, uniV2Router, }) => {
|
|
174
120
|
return multicallRead({
|
|
175
121
|
chain: chainsMetadata[chain],
|
|
176
122
|
client,
|
|
177
123
|
abi: abis.univ2Router,
|
|
178
|
-
// pulsex router
|
|
179
|
-
// a chain with no router reads nothing, as lodash's flatMap over undefined did
|
|
180
124
|
calls: (uniV2Router ? [uniV2Router] : (uniV2Routers[chain] ?? [])).flatMap((target) => paths.map((path) => ({
|
|
181
125
|
functionName: 'getAmountsOut',
|
|
182
126
|
allowFailure: true,
|
|
@@ -185,22 +129,9 @@ const readAmountOut = ({ amountIn, chain, paths, client, uniV2Router, }) => {
|
|
|
185
129
|
}))),
|
|
186
130
|
});
|
|
187
131
|
};
|
|
188
|
-
/**
|
|
189
|
-
* Fetch the price corrective for the given bridge key, asset out, measurement token, from chain client, to chain client, asset link, amount in, and is prod
|
|
190
|
-
* @param bridgeKeyPartner - the bridge key partner
|
|
191
|
-
* @param assetOut - the asset out
|
|
192
|
-
* @param measurementToken - the measurement token
|
|
193
|
-
* @param fromChainClient - the from chain client
|
|
194
|
-
* @param toChainClient - the to chain client
|
|
195
|
-
* @param assetLink - the asset link
|
|
196
|
-
* @param amountIn - the amount in
|
|
197
|
-
* @param isProd - whether to use the production pathway
|
|
198
|
-
* @returns the price corrective
|
|
199
|
-
*/
|
|
200
132
|
export const fetchPriceCorrective = ({ bridgeKeyPartner, assetOut, measurementToken, fromChainClient, toChainClient, assetLink, amountIn, isProd, }) => {
|
|
201
133
|
return {
|
|
202
134
|
getPaymentToken: async () => {
|
|
203
|
-
// fetch the token bridge info for the token that is about to be spent by the delivery service
|
|
204
135
|
return await tokenBridgeInfo({
|
|
205
136
|
bridgeKey: bridgeKeyPartner,
|
|
206
137
|
assetIn: {
|
|
@@ -208,8 +139,6 @@ export const fetchPriceCorrective = ({ bridgeKeyPartner, assetOut, measurementTo
|
|
|
208
139
|
address: measurementToken,
|
|
209
140
|
},
|
|
210
141
|
isProd,
|
|
211
|
-
// clients are reversed here because we are actually fetching the
|
|
212
|
-
// tokens going the opposite direction to the provided bridge key
|
|
213
142
|
fromChainClient: toChainClient,
|
|
214
143
|
toChainClient: fromChainClient,
|
|
215
144
|
});
|
|
@@ -222,9 +151,7 @@ export const fetchPriceCorrective = ({ bridgeKeyPartner, assetOut, measurementTo
|
|
|
222
151
|
uniV2Router,
|
|
223
152
|
client,
|
|
224
153
|
paths: [
|
|
225
|
-
// check the direct route
|
|
226
154
|
[assetLink.assetInAddress, paymentTokenResult.assetOutAddress],
|
|
227
|
-
// might have heavier liquidity going through the native asset on the home side
|
|
228
155
|
[assetLink.assetInAddress, nativeAssetOut[chain], paymentTokenResult.assetOutAddress],
|
|
229
156
|
],
|
|
230
157
|
}),
|
|
@@ -234,22 +161,17 @@ export const fetchPriceCorrective = ({ bridgeKeyPartner, assetOut, measurementTo
|
|
|
234
161
|
uniV2Router,
|
|
235
162
|
client,
|
|
236
163
|
paths: [[assetOut.address, measurementToken]],
|
|
237
|
-
// only the direct route is available.
|
|
238
|
-
// might be able to create a whitelist for this at some point
|
|
239
164
|
}),
|
|
240
165
|
]);
|
|
241
166
|
},
|
|
242
167
|
reduceResults: ({ results, oneToken, }) => {
|
|
243
168
|
const outputFromRouter = (result) => {
|
|
244
169
|
if (typeof result === 'string') {
|
|
245
|
-
// the router failed to return a result
|
|
246
170
|
return 0n;
|
|
247
171
|
}
|
|
248
172
|
if (!result.length) {
|
|
249
|
-
// the router returned an empty result
|
|
250
173
|
return 0n;
|
|
251
174
|
}
|
|
252
|
-
// the last element is the amount of the output token
|
|
253
175
|
const last = result[result.length - 1];
|
|
254
176
|
return (last * oneToken) / amountIn;
|
|
255
177
|
};
|
|
@@ -258,7 +180,6 @@ export const fetchPriceCorrective = ({ bridgeKeyPartner, assetOut, measurementTo
|
|
|
258
180
|
.filter((amount) => amount !== undefined)
|
|
259
181
|
.reduce((max, current) => (max < current ? current : max), 0n);
|
|
260
182
|
};
|
|
261
|
-
// could do with a refactor to unify the results
|
|
262
183
|
const [outputs, inputs] = results;
|
|
263
184
|
const outputAmounts = outputs.map(outputFromRouter);
|
|
264
185
|
const inputAmounts = inputs.map(outputFromRouter);
|
|
@@ -273,36 +194,12 @@ export const fetchPriceCorrective = ({ bridgeKeyPartner, assetOut, measurementTo
|
|
|
273
194
|
},
|
|
274
195
|
};
|
|
275
196
|
};
|
|
276
|
-
/**
|
|
277
|
-
* Read the smallest amount the bridge will accept for this asset on this pathway.
|
|
278
|
-
*
|
|
279
|
-
* THE ENTRY MEDIATOR DECIDES, so this always reads `pathway.from` on the chain
|
|
280
|
-
* the funds leave. `feeManager` says which side prices the transfer; it has
|
|
281
|
-
* never said which side validates the amount, and using it for both is what
|
|
282
|
-
* produced the defect this replaces.
|
|
283
|
-
*
|
|
284
|
-
* Both mediators keep a `minPerTx` under the same name, and for a token that
|
|
285
|
-
* originates on the entry chain the two sides usually hold the same number. That
|
|
286
|
-
* agreement is a coincidence of configuration - each side is separately
|
|
287
|
-
* governed, and both happen to apply one blanket default. It breaks outright for
|
|
288
|
-
* a token that originates on the far side, because the two mediators key their
|
|
289
|
-
* limits by different addresses. Wrapped Pulse entering from Ethereum is the
|
|
290
|
-
* live case: the entry mediator enforces 50,000, and the destination mediator
|
|
291
|
-
* answers 0 for that same address because it files that token under its
|
|
292
|
-
* PulseChain address instead. Reading the destination got both the chain and the
|
|
293
|
-
* token key wrong, and reported no floor where a real one stood.
|
|
294
|
-
* @param assetIn - the asset the sender holds, on the chain it leaves from
|
|
295
|
-
* @param pathway - the pathway, with any per-asset overrides already applied
|
|
296
|
-
* @param fromPublicClient - a client for the chain the funds leave
|
|
297
|
-
* @returns the smallest amount the entry mediator will accept
|
|
298
|
-
*/
|
|
299
197
|
export const minBridgeAmountIn = async ({ assetIn, pathway, fromPublicClient, }) => fromPublicClient.readContract({
|
|
300
198
|
abi: abis.inputBridge,
|
|
301
199
|
functionName: 'minPerTx',
|
|
302
200
|
args: [assetIn.address],
|
|
303
201
|
address: pathway.from,
|
|
304
202
|
});
|
|
305
|
-
/** get the symbol of the native asset, unwrap it if it needs to be */
|
|
306
203
|
export const nativeSymbol = (asset, unwrap = false) => {
|
|
307
204
|
return asset
|
|
308
205
|
? unwrap && asset.address === nativeAssetOut[toChain(asset.chainId)]
|
|
@@ -310,12 +207,6 @@ export const nativeSymbol = (asset, unwrap = false) => {
|
|
|
310
207
|
: asset.symbol
|
|
311
208
|
: '';
|
|
312
209
|
};
|
|
313
|
-
/**
|
|
314
|
-
* Returns the Multicall3 contract for the client's chain.
|
|
315
|
-
* @param client - a client whose `chain` is one of {@link chainsMetadata}'s chains
|
|
316
|
-
* @returns the Multicall3 contract instance
|
|
317
|
-
* @throws when the client carries no chain, or the chain has no Multicall3 address
|
|
318
|
-
*/
|
|
319
210
|
export const chainMulticall = (client) => {
|
|
320
211
|
const chainId = client.chain?.id;
|
|
321
212
|
if (chainId === undefined) {
|
|
@@ -327,13 +218,6 @@ export const chainMulticall = (client) => {
|
|
|
327
218
|
}
|
|
328
219
|
return getContract({ abi: multicall3Abi, client, address });
|
|
329
220
|
};
|
|
330
|
-
/**
|
|
331
|
-
* Load the bridge fees for the given pathway, from chain client, and to chain client
|
|
332
|
-
* @param pathway - the pathway
|
|
333
|
-
* @param fromChainClient - the from chain client
|
|
334
|
-
* @param toChainClient - the to chain client
|
|
335
|
-
* @returns the bridge fees
|
|
336
|
-
*/
|
|
337
221
|
export const loadBridgeFees = async ({ pathway, fromChainClient, toChainClient, }) => {
|
|
338
222
|
const multicall = pathway.feeManager === 'from' ? chainMulticall(fromChainClient) : chainMulticall(toChainClient);
|
|
339
223
|
const [feeManagerResponse] = await multicall.read.aggregate3([
|
package/dist/chain-names.js
CHANGED
|
@@ -1,117 +1,22 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Chain identifiers and their human-readable display names, in one place.
|
|
3
|
-
*
|
|
4
|
-
* This module exists to break an import cycle. `relay-quote.ts` imports the
|
|
5
|
-
* step normalizers from `route-steps.ts`, and `route-steps.ts` needs to name
|
|
6
|
-
* Relay's non-Ethereum chains when it labels a leg. Holding the shared lookup
|
|
7
|
-
* here lets both import it without either importing the other.
|
|
8
|
-
*
|
|
9
|
-
* Names are spelled out in full — these strings are shown to someone choosing
|
|
10
|
-
* where their funds leave from, so "The Open Network", never "TON".
|
|
11
|
-
*/
|
|
12
|
-
/**
|
|
13
|
-
* Relay's numeric chain identifiers for the non-Ethereum-Virtual-Machine origin
|
|
14
|
-
* chains this bridge supports. These are Relay's OWN identifiers, distinct from
|
|
15
|
-
* any native chain id, and are required verbatim as the request's
|
|
16
|
-
* `originChainId`.
|
|
17
|
-
*
|
|
18
|
-
* Source: https://api.relay.link/chains, where each entry's `vmType` names the
|
|
19
|
-
* ecosystem and each is reported `depositEnabled`.
|
|
20
|
-
*/
|
|
21
1
|
export const relayChainIds = {
|
|
22
|
-
/** Relay's chain id for Solana mainnet (virtual-machine type `svm`). */
|
|
23
2
|
solana: 792703809,
|
|
24
|
-
/**
|
|
25
|
-
* Relay's chain id for Eclipse (virtual-machine type `svm`) — a SECOND chain
|
|
26
|
-
* in the Solana ecosystem, sharing Solana's address encoding, deposit shape
|
|
27
|
-
* and native-asset sentinel while being a different network with a different
|
|
28
|
-
* native asset (Ether, not Sol).
|
|
29
|
-
*
|
|
30
|
-
* Quotable, but see the guard in the interface's Solana signer: sharing an
|
|
31
|
-
* ecosystem means sharing a wallet adapter, and that adapter is bound to ONE
|
|
32
|
-
* Solana network at a time. A deposit for this chain must never be signed
|
|
33
|
-
* against a connection pointed at Solana.
|
|
34
|
-
*/
|
|
35
3
|
eclipse: 9286185,
|
|
36
|
-
/** Relay's chain id for Bitcoin mainnet (virtual-machine type `bvm`). */
|
|
37
4
|
bitcoin: 8253038,
|
|
38
|
-
/** Relay's chain id for Tron mainnet (virtual-machine type `tvm`). */
|
|
39
5
|
tron: 728126428,
|
|
40
|
-
/** Relay's chain id for The Open Network (virtual-machine type `tonvm`). */
|
|
41
6
|
ton: 224235520,
|
|
42
|
-
/**
|
|
43
|
-
* Relay's chain id for Hyperliquid (virtual-machine type `hypevm`).
|
|
44
|
-
*
|
|
45
|
-
* BEWARE: 1337 is also the default chain id of a local Ganache development
|
|
46
|
-
* node, so this is the one Relay identifier that can collide with a real
|
|
47
|
-
* Ethereum Virtual Machine chain a developer might be running. Treating a
|
|
48
|
-
* local test chain as Hyperliquid would route it down the HyperCore deposit
|
|
49
|
-
* path, so never feed a local development chain id through
|
|
50
|
-
* `ecosystemByChainId`.
|
|
51
|
-
*/
|
|
52
7
|
hyperliquid: 1337,
|
|
53
8
|
};
|
|
54
|
-
/**
|
|
55
|
-
* Chain identifiers for origin chains a reader PAYS BY HAND.
|
|
56
|
-
*
|
|
57
|
-
* WHAT MAKES THESE DIFFERENT FROM EVERY OTHER CHAIN HERE. Every identifier
|
|
58
|
-
* above names a chain this interface can connect a wallet to and sign on.
|
|
59
|
-
* These name chains it cannot. There is no connector, no signer and no
|
|
60
|
-
* transaction: the provider issues an address, the reader sends an ordinary
|
|
61
|
-
* transfer to it from any wallet or any exchange, and the provider's own
|
|
62
|
-
* watcher reports the arrival. The chain identifier exists so the route layer
|
|
63
|
-
* can NAME the chain, price it and draw it — nothing more.
|
|
64
|
-
*
|
|
65
|
-
* THE NUMBERS ARE DERIVED, NOT INVENTED, and the derivation is written down
|
|
66
|
-
* because a chain identifier typed from memory is a hypothesis every later
|
|
67
|
-
* reader will trust. Each is the chain's registered SLIP-0044 coin type with
|
|
68
|
-
* the hardened bit set, exactly as a BIP-44 derivation path writes it:
|
|
69
|
-
* `0x80000000 + coinType`. That puts them above every chain identifier in
|
|
70
|
-
* public use, so one can never collide with a real Ethereum chain and be
|
|
71
|
-
* mistaken for one — which is the failure that matters, because an Ethereum
|
|
72
|
-
* chain has a wallet and would be handed a payload to sign.
|
|
73
|
-
*
|
|
74
|
-
* They are LOCAL identifiers and never travel on a wire. NEAR Intents names
|
|
75
|
-
* Zcash `zec`; `chainIdByNearIntentsChain` is where the two are reconciled.
|
|
76
|
-
*/
|
|
77
9
|
export const depositAddressChainIds = {
|
|
78
|
-
/** Zcash mainnet. SLIP-0044 coin type 133, hardened: 0x80000000 + 133. */
|
|
79
10
|
zcash: 2_147_483_781,
|
|
80
11
|
};
|
|
81
|
-
/**
|
|
82
|
-
* Display names for the chains a reader pays by hand, one entry per member of
|
|
83
|
-
* {@link DepositAddressChain}. Typed on the union rather than on `number` so a
|
|
84
|
-
* chain added to {@link depositAddressChainIds} without a name here is a
|
|
85
|
-
* compile error, not a blank badge.
|
|
86
|
-
*/
|
|
87
12
|
const depositAddressChainNamesByChain = {
|
|
88
13
|
zcash: 'Zcash',
|
|
89
14
|
};
|
|
90
|
-
/** {@link depositAddressChainNamesByChain}, keyed by chain id for lookup. */
|
|
91
15
|
const depositAddressChainNames = new Map(Object.keys(depositAddressChainIds).map((chain) => [
|
|
92
16
|
depositAddressChainIds[chain],
|
|
93
17
|
depositAddressChainNamesByChain[chain],
|
|
94
18
|
]));
|
|
95
|
-
/**
|
|
96
|
-
* Whether a chain identifier names a chain this interface CANNOT SIGN ON.
|
|
97
|
-
*
|
|
98
|
-
* The one predicate every surface asks before offering a wallet. A chain that
|
|
99
|
-
* answers true has no connector, so anything that would connect, switch
|
|
100
|
-
* networks, estimate gas or compose a transaction for it is wrong — the reader
|
|
101
|
-
* is shown an address to pay instead.
|
|
102
|
-
*
|
|
103
|
-
* @param chainId - a chain identifier
|
|
104
|
-
* @returns whether the reader pays this chain by hand
|
|
105
|
-
*/
|
|
106
19
|
export const isDepositAddressChain = (chainId) => depositAddressChainNames.has(chainId);
|
|
107
|
-
/**
|
|
108
|
-
* Display names for Relay's non-Ethereum origin chains.
|
|
109
|
-
*
|
|
110
|
-
* An ecosystem label is NOT a chain name, and using one as a name is actively
|
|
111
|
-
* wrong: `svm` holds both Solana and Eclipse, so labelling by ecosystem renders
|
|
112
|
-
* Eclipse as "Solana" — a different network, shown to someone choosing where
|
|
113
|
-
* their funds leave from. Keyed by chain id for exactly that reason.
|
|
114
|
-
*/
|
|
115
20
|
export const relayChainNames = new Map([
|
|
116
21
|
[relayChainIds.solana, 'Solana'],
|
|
117
22
|
[relayChainIds.eclipse, 'Eclipse'],
|
|
@@ -120,11 +25,6 @@ export const relayChainNames = new Map([
|
|
|
120
25
|
[relayChainIds.ton, 'The Open Network'],
|
|
121
26
|
[relayChainIds.hyperliquid, 'Hyperliquid'],
|
|
122
27
|
]);
|
|
123
|
-
/**
|
|
124
|
-
* Display names for the Ethereum-Virtual-Machine chains a route can traverse.
|
|
125
|
-
* Only the chains this bridge actually routes through need an entry; anything
|
|
126
|
-
* else falls back to its numeric identifier rather than being dropped.
|
|
127
|
-
*/
|
|
128
28
|
const virtualMachineChainNames = new Map([
|
|
129
29
|
[1, 'Ethereum'],
|
|
130
30
|
[56, 'Binance Smart Chain'],
|
|
@@ -133,28 +33,7 @@ const virtualMachineChainNames = new Map([
|
|
|
133
33
|
[42161, 'Arbitrum One'],
|
|
134
34
|
[11155111, 'Sepolia'],
|
|
135
35
|
]);
|
|
136
|
-
/**
|
|
137
|
-
* Names registered at startup from the wider chain registry.
|
|
138
|
-
*
|
|
139
|
-
* This package cannot import that registry — it sits below the client that
|
|
140
|
-
* holds it — but it must still be the ONE place a chain name is decided. The
|
|
141
|
-
* alternative was what this replaced: three resolvers, each with different
|
|
142
|
-
* coverage, so the same chain read as "Base" beside one element, "chain 8453"
|
|
143
|
-
* beside another, and vanished entirely from a third. A reader hovering two
|
|
144
|
-
* parts of the same row saw two different answers.
|
|
145
|
-
*/
|
|
146
36
|
const registeredChainNames = new Map();
|
|
147
|
-
/**
|
|
148
|
-
* Registers display names for chains this module does not know about.
|
|
149
|
-
*
|
|
150
|
-
* Call once during startup, before anything renders. Entries are merged, and a
|
|
151
|
-
* name declared in `virtualMachineChainNames` above WINS over a registered one:
|
|
152
|
-
* the local table is deliberate ("Binance Smart Chain", not the registry's
|
|
153
|
-
* "BNB Smart Chain"), and a registry that happens to disagree must not quietly
|
|
154
|
-
* rename a chain the product has already named.
|
|
155
|
-
*
|
|
156
|
-
* @param entries - chain id and display name pairs
|
|
157
|
-
*/
|
|
158
37
|
export const registerChainNames = (entries) => {
|
|
159
38
|
for (const [chainId, name] of entries) {
|
|
160
39
|
if (!name)
|
|
@@ -162,37 +41,7 @@ export const registerChainNames = (entries) => {
|
|
|
162
41
|
registeredChainNames.set(chainId, name);
|
|
163
42
|
}
|
|
164
43
|
};
|
|
165
|
-
/**
|
|
166
|
-
* Returns a human-readable chain name for the given chain id, covering both
|
|
167
|
-
* Ethereum-Virtual-Machine chains and Relay's non-Ethereum pseudo identifiers.
|
|
168
|
-
*
|
|
169
|
-
* Falls back to the numeric id stringified when the chain is not known — better
|
|
170
|
-
* to show "chain 999" than to silently drop the leg that traverses it.
|
|
171
|
-
*
|
|
172
|
-
* @param chainId - a decimal chain id, Relay's identifier included
|
|
173
|
-
* @returns the display name, or `chain <id>` when unknown
|
|
174
|
-
*/
|
|
175
44
|
export const chainDisplayName = (chainId) => knownChainName(chainId) ?? `chain ${chainId}`;
|
|
176
|
-
/**
|
|
177
|
-
* The name this module KNOWS for a chain, or null when it knows none.
|
|
178
|
-
*
|
|
179
|
-
* Same lookup as {@link chainDisplayName} without the placeholder, so a caller
|
|
180
|
-
* with a better fallback of its own can reach one. {@link chainDisplayName} is
|
|
181
|
-
* defined in terms of this, which is the point: the two can never disagree
|
|
182
|
-
* about which chains are known.
|
|
183
|
-
*
|
|
184
|
-
* WHY A CALLER WOULD WANT THIS. The network chips in the token picker have a
|
|
185
|
-
* second name to fall back on — the aggregator's own chain list, which reaches
|
|
186
|
-
* chains this registry has never been told about and says "Unknown network"
|
|
187
|
-
* rather than printing a bare number. Choosing between the two used to be done
|
|
188
|
-
* by comparing `chainDisplayName`'s answer against the literal string
|
|
189
|
-
* `chain <id>`, which is a caller reaching into another function's fallback
|
|
190
|
-
* format: rename the placeholder here and that comparison quietly stops
|
|
191
|
-
* matching, leaving every unknown chain labelled with its number.
|
|
192
|
-
*
|
|
193
|
-
* @param chainId - a decimal chain id, Relay's identifiers included
|
|
194
|
-
* @returns the display name, or null when the chain is not known here
|
|
195
|
-
*/
|
|
196
45
|
export const knownChainName = (chainId) => virtualMachineChainNames.get(chainId) ??
|
|
197
46
|
relayChainNames.get(chainId) ??
|
|
198
47
|
depositAddressChainNames.get(chainId) ??
|