@gibs/bridge-sdk 1.13.0 → 1.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (217) hide show
  1. package/README.md +244 -18
  2. package/abis/package.json +6 -0
  3. package/bridge-limits/package.json +6 -0
  4. package/chain-info/package.json +6 -0
  5. package/chain-names/package.json +6 -0
  6. package/chains/package.json +6 -0
  7. package/claims/package.json +6 -0
  8. package/config/package.json +6 -0
  9. package/consolidated-quote/package.json +6 -0
  10. package/destination-calldata/package.json +6 -0
  11. package/dist/chain-info.d.ts +1 -1
  12. package/dist/chain-info.js +11 -12
  13. package/dist/chains.d.ts +25 -0
  14. package/dist/chains.js +55 -20
  15. package/dist/cjs/abis.d.ts +1 -0
  16. package/dist/cjs/abis.js +19 -0
  17. package/dist/cjs/bridge-limits.d.ts +103 -0
  18. package/dist/cjs/bridge-limits.js +89 -0
  19. package/dist/cjs/chain-info.d.ts +169 -0
  20. package/dist/cjs/chain-info.js +452 -0
  21. package/dist/cjs/chain-names.d.ts +160 -0
  22. package/dist/cjs/chain-names.js +207 -0
  23. package/dist/cjs/chains.d.ts +90 -0
  24. package/dist/cjs/chains.js +357 -0
  25. package/dist/cjs/claims.d.ts +198 -0
  26. package/dist/cjs/claims.js +182 -0
  27. package/dist/cjs/config.d.ts +240 -0
  28. package/dist/cjs/config.js +537 -0
  29. package/dist/cjs/consolidated-quote.d.ts +648 -0
  30. package/dist/cjs/consolidated-quote.js +1048 -0
  31. package/dist/cjs/destination-calldata.d.ts +118 -0
  32. package/dist/cjs/destination-calldata.js +156 -0
  33. package/dist/cjs/ecosystems.d.ts +217 -0
  34. package/dist/cjs/ecosystems.js +298 -0
  35. package/dist/cjs/execution.d.ts +346 -0
  36. package/dist/cjs/execution.js +468 -0
  37. package/dist/cjs/fee-type.d.ts +10 -0
  38. package/dist/cjs/fee-type.js +10 -0
  39. package/dist/cjs/hyperliquid-execution.d.ts +152 -0
  40. package/dist/cjs/hyperliquid-execution.js +175 -0
  41. package/dist/cjs/image-links.d.ts +117 -0
  42. package/dist/cjs/image-links.js +153 -0
  43. package/dist/cjs/index.d.ts +23 -0
  44. package/dist/cjs/index.js +39 -0
  45. package/dist/cjs/lifi-execution-guard.d.ts +210 -0
  46. package/dist/cjs/lifi-execution-guard.js +409 -0
  47. package/dist/cjs/near-intents-conformance.d.ts +85 -0
  48. package/dist/cjs/near-intents-conformance.js +337 -0
  49. package/dist/cjs/near-intents-route.d.ts +47 -0
  50. package/dist/cjs/near-intents-route.js +303 -0
  51. package/dist/cjs/near-intents.d.ts +524 -0
  52. package/dist/cjs/near-intents.js +1071 -0
  53. package/dist/cjs/origin-deposit.d.ts +326 -0
  54. package/dist/cjs/origin-deposit.js +82 -0
  55. package/dist/cjs/package.json +3 -0
  56. package/dist/cjs/pre-quote.d.ts +198 -0
  57. package/dist/cjs/pre-quote.js +180 -0
  58. package/dist/cjs/prices.d.ts +107 -0
  59. package/dist/cjs/prices.js +172 -0
  60. package/dist/cjs/providers.d.ts +238 -0
  61. package/dist/cjs/providers.js +171 -0
  62. package/dist/cjs/quote-fees.d.ts +102 -0
  63. package/dist/cjs/quote-fees.js +201 -0
  64. package/dist/cjs/referral.d.ts +85 -0
  65. package/dist/cjs/referral.js +85 -0
  66. package/dist/cjs/relay-currencies.d.ts +47 -0
  67. package/dist/cjs/relay-currencies.js +95 -0
  68. package/dist/cjs/relay-depository.d.ts +2 -0
  69. package/dist/cjs/relay-depository.js +85 -0
  70. package/dist/cjs/relay-quote.d.ts +301 -0
  71. package/dist/cjs/relay-quote.js +996 -0
  72. package/dist/cjs/route-steps.d.ts +138 -0
  73. package/dist/cjs/route-steps.js +310 -0
  74. package/dist/cjs/routing/amounts.d.ts +80 -0
  75. package/dist/cjs/routing/amounts.js +126 -0
  76. package/dist/cjs/routing/candidate-route.d.ts +43 -0
  77. package/dist/cjs/routing/candidate-route.js +50 -0
  78. package/dist/cjs/routing/candidate.d.ts +237 -0
  79. package/dist/cjs/routing/candidate.js +100 -0
  80. package/dist/cjs/routing/carriers/ask-answer.d.ts +77 -0
  81. package/dist/cjs/routing/carriers/ask-answer.js +2 -0
  82. package/dist/cjs/routing/carriers/omnibridge.d.ts +137 -0
  83. package/dist/cjs/routing/carriers/omnibridge.js +459 -0
  84. package/dist/cjs/routing/carriers/pulsex-paths.d.ts +80 -0
  85. package/dist/cjs/routing/carriers/pulsex-paths.js +97 -0
  86. package/dist/cjs/routing/carriers/pulsex-split.d.ts +175 -0
  87. package/dist/cjs/routing/carriers/pulsex-split.js +193 -0
  88. package/dist/cjs/routing/carriers/pulsex.d.ts +159 -0
  89. package/dist/cjs/routing/carriers/pulsex.js +565 -0
  90. package/dist/cjs/routing/carriers/wrap.d.ts +25 -0
  91. package/dist/cjs/routing/carriers/wrap.js +119 -0
  92. package/dist/cjs/routing/composed-route-quality.d.ts +125 -0
  93. package/dist/cjs/routing/composed-route-quality.js +144 -0
  94. package/dist/cjs/routing/entry-chain-anchor.d.ts +88 -0
  95. package/dist/cjs/routing/entry-chain-anchor.js +59 -0
  96. package/dist/cjs/routing/format.d.ts +31 -0
  97. package/dist/cjs/routing/format.js +64 -0
  98. package/dist/cjs/routing/index.d.ts +38 -0
  99. package/dist/cjs/routing/index.js +134 -0
  100. package/dist/cjs/routing/producers.d.ts +770 -0
  101. package/dist/cjs/routing/producers.js +1617 -0
  102. package/dist/cjs/routing/providers.d.ts +31 -0
  103. package/dist/cjs/routing/providers.js +48 -0
  104. package/dist/cjs/routing/route-data.d.ts +355 -0
  105. package/dist/cjs/routing/route-data.js +2 -0
  106. package/dist/cjs/routing/search/compose.d.ts +168 -0
  107. package/dist/cjs/routing/search/compose.js +104 -0
  108. package/dist/cjs/routing/search/graph.d.ts +668 -0
  109. package/dist/cjs/routing/search/graph.js +461 -0
  110. package/dist/cjs/routing/search/plan-route-data.d.ts +269 -0
  111. package/dist/cjs/routing/search/plan-route-data.js +848 -0
  112. package/dist/cjs/routing/search/score.d.ts +356 -0
  113. package/dist/cjs/routing/search/score.js +445 -0
  114. package/dist/cjs/routing/swap-transactions.d.ts +91 -0
  115. package/dist/cjs/routing/swap-transactions.js +131 -0
  116. package/dist/cjs/routing/usd-value.d.ts +17 -0
  117. package/dist/cjs/routing/usd-value.js +29 -0
  118. package/dist/cjs/settings.d.ts +785 -0
  119. package/dist/cjs/settings.js +1074 -0
  120. package/dist/cjs/ton-connect.d.ts +98 -0
  121. package/dist/cjs/ton-connect.js +206 -0
  122. package/dist/cjs/ton-execution.d.ts +7 -0
  123. package/dist/cjs/ton-execution.js +23 -0
  124. package/dist/cjs/ton.d.ts +37 -0
  125. package/dist/cjs/ton.js +83 -0
  126. package/dist/cjs/tron-execution.d.ts +146 -0
  127. package/dist/cjs/tron-execution.js +248 -0
  128. package/dist/cjs/types.d.ts +51 -0
  129. package/dist/cjs/types.js +2 -0
  130. package/dist/claims.d.ts +198 -0
  131. package/dist/claims.js +140 -0
  132. package/dist/config.d.ts +24 -0
  133. package/dist/config.js +39 -5
  134. package/dist/consolidated-quote.d.ts +109 -15
  135. package/dist/consolidated-quote.js +310 -52
  136. package/dist/execution.d.ts +346 -0
  137. package/dist/execution.js +428 -0
  138. package/dist/hyperliquid-execution.js +2 -3
  139. package/dist/index.d.ts +3 -0
  140. package/dist/index.js +3 -0
  141. package/dist/lifi-execution-guard.d.ts +13 -2
  142. package/dist/lifi-execution-guard.js +4 -0
  143. package/dist/near-intents.js +2 -3
  144. package/dist/pre-quote.d.ts +6 -6
  145. package/dist/pre-quote.js +10 -14
  146. package/dist/providers.d.ts +17 -0
  147. package/dist/providers.js +6 -0
  148. package/dist/referral.d.ts +12 -4
  149. package/dist/referral.js +12 -4
  150. package/dist/relay-depository.d.ts +2 -0
  151. package/dist/relay-depository.js +82 -0
  152. package/dist/relay-quote.js +2 -3
  153. package/dist/routing/candidate.d.ts +3 -3
  154. package/dist/routing/candidate.js +3 -3
  155. package/dist/routing/carriers/ask-answer.d.ts +19 -0
  156. package/dist/routing/carriers/omnibridge.js +23 -21
  157. package/dist/routing/carriers/pulsex-paths.d.ts +80 -0
  158. package/dist/routing/carriers/pulsex-paths.js +92 -0
  159. package/dist/routing/carriers/pulsex-split.d.ts +175 -0
  160. package/dist/routing/carriers/pulsex-split.js +185 -0
  161. package/dist/routing/carriers/pulsex.d.ts +69 -21
  162. package/dist/routing/carriers/pulsex.js +184 -65
  163. package/dist/routing/composed-route-quality.d.ts +28 -6
  164. package/dist/routing/composed-route-quality.js +36 -5
  165. package/dist/routing/entry-chain-anchor.d.ts +1 -1
  166. package/dist/routing/entry-chain-anchor.js +1 -1
  167. package/dist/routing/index.d.ts +7 -3
  168. package/dist/routing/index.js +7 -3
  169. package/dist/routing/producers.js +1 -1
  170. package/dist/routing/providers.d.ts +5 -0
  171. package/dist/routing/providers.js +5 -0
  172. package/dist/routing/search/graph.d.ts +29 -0
  173. package/dist/routing/search/plan-route-data.d.ts +25 -0
  174. package/dist/routing/search/plan-route-data.js +43 -7
  175. package/dist/routing/search/score.d.ts +33 -1
  176. package/dist/routing/search/score.js +41 -6
  177. package/dist/routing/swap-transactions.d.ts +91 -0
  178. package/dist/routing/swap-transactions.js +125 -0
  179. package/dist/settings.d.ts +94 -1
  180. package/dist/settings.js +95 -3
  181. package/dist/ton-connect.d.ts +98 -0
  182. package/dist/ton-connect.js +200 -0
  183. package/dist/ton-execution.d.ts +4 -114
  184. package/dist/ton-execution.js +4 -244
  185. package/dist/ton.d.ts +37 -0
  186. package/dist/ton.js +65 -0
  187. package/docs/examples/example-a-ether-to-pulse.ts +300 -0
  188. package/docs/examples/example-b-token-pulsechain-to-ethereum.ts +270 -0
  189. package/docs/examples/shared.ts +261 -0
  190. package/docs/examples/tsconfig.json +18 -0
  191. package/docs/integration-guide.md +617 -0
  192. package/ecosystems/package.json +6 -0
  193. package/execution/package.json +6 -0
  194. package/fee-type/package.json +6 -0
  195. package/hyperliquid-execution/package.json +6 -0
  196. package/image-links/package.json +6 -0
  197. package/lifi-execution-guard/package.json +6 -0
  198. package/llms.txt +234 -0
  199. package/near-intents/package.json +6 -0
  200. package/near-intents-route/package.json +6 -0
  201. package/origin-deposit/package.json +6 -0
  202. package/package.json +818 -10
  203. package/pre-quote/package.json +6 -0
  204. package/prices/package.json +6 -0
  205. package/providers/package.json +6 -0
  206. package/quote-fees/package.json +6 -0
  207. package/referral/package.json +6 -0
  208. package/relay-currencies/package.json +6 -0
  209. package/relay-quote/package.json +6 -0
  210. package/route-steps/package.json +6 -0
  211. package/routing/package.json +6 -0
  212. package/settings/package.json +6 -0
  213. package/ton/package.json +6 -0
  214. package/ton-connect/package.json +6 -0
  215. package/ton-execution/package.json +6 -0
  216. package/tron-execution/package.json +6 -0
  217. package/types/package.json +6 -0
@@ -0,0 +1,452 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.loadBridgeFees = exports.chainMulticall = exports.nativeSymbol = exports.minBridgeAmountIn = exports.fetchPriceCorrective = exports.tokenBridgeInfo = exports.clearChainInfoCaches = exports.links = void 0;
37
+ const cache_1 = require("@gibs/common/cache");
38
+ const multicall_1 = require("@gibs/common/multicall");
39
+ const viem_1 = require("viem");
40
+ const abis = __importStar(require("./abis.js"));
41
+ const chains_js_1 = require("./chains.js");
42
+ const config_js_1 = require("./config.js");
43
+ /** Cache key for the links memoize: one entry per (chain, bridge, token) triple. */
44
+ const linksCacheKey = ({ chainId, target, address, }) => `${chainId}-${target}-${address}`.toLowerCase();
45
+ /**
46
+ * Whether a {@link links} answer says the token has no mapping on this bridge
47
+ * yet. That answer is temporary: the first transfer of the token creates the
48
+ * mapping, so it must not be cached.
49
+ * @param pair - the bridged and native addresses the mediator returned
50
+ * @returns true when both are the zero address
51
+ */
52
+ const isUnmappedAnswer = ([bridged, native]) => bridged === viem_1.zeroAddress && native === viem_1.zeroAddress;
53
+ /**
54
+ * Returns the bridged token address and native token address that a mediator
55
+ * holds for one token.
56
+ *
57
+ * A non-zero answer is cached for the life of the process: a mediator never
58
+ * changes a mapping once the first transfer creates it. A failed read, and a
59
+ * `[zero, zero]` answer (the token is not bridged yet), are not cached, so the
60
+ * next call reads the chain again. Call {@link clearChainInfoCaches} to drop
61
+ * every cached answer.
62
+ *
63
+ * @param inputs.chainId - the chain id being targeted
64
+ * @param inputs.target - the mediator to ask
65
+ * @param inputs.address - the token address
66
+ * @param inputs.client - a client for that chain
67
+ * @returns the bridged token address and native token address
68
+ */
69
+ // The body reaches for `links.cache` to evict an answer, so the cache surface
70
+ // is spelled out to the extent this file uses it.
71
+ exports.links = (0, cache_1.memoizeByKey)(async (inputs) => {
72
+ const { chainId, target, address, client } = inputs;
73
+ const evict = () => exports.links.cache.delete(linksCacheKey(inputs));
74
+ const pair = await (0, multicall_1.multicallRead)({
75
+ client,
76
+ chain: chains_js_1.chainsMetadata[(0, config_js_1.toChain)(chainId)],
77
+ abi: abis.inputBridge,
78
+ target,
79
+ calls: [
80
+ { functionName: 'bridgedTokenAddress', args: [address] },
81
+ { functionName: 'nativeTokenAddress', args: [address] },
82
+ ],
83
+ }).catch((error) => {
84
+ // a transient read failure must not poison the cache for the session
85
+ evict();
86
+ throw error;
87
+ });
88
+ if (isUnmappedAnswer(pair)) {
89
+ // the token may be bridged a minute from now; ask again next time
90
+ evict();
91
+ }
92
+ return pair;
93
+ }, linksCacheKey);
94
+ /**
95
+ * Drops every answer this module has cached, so the next read goes to the chain.
96
+ *
97
+ * Use it after a token's first transfer, in a long-running process that wants
98
+ * a fresh view, or between tests.
99
+ */
100
+ const clearChainInfoCaches = () => {
101
+ exports.links.cache.clear();
102
+ };
103
+ exports.clearChainInfoCaches = clearChainInfoCaches;
104
+ /**
105
+ * Returns the token bridge info for the given bridge key, asset in, is prod, from chain client, and to chain client
106
+ * @param bridgeKey - the bridge key
107
+ * @param assetIn - the asset in
108
+ * @param isProd - whether to use the production pathway
109
+ * @param fromChainClient - the from chain client
110
+ * @param toChainClient - the to chain client
111
+ * @returns the token bridge info
112
+ */
113
+ const tokenBridgeInfo = async ({ bridgeKey, assetIn, isProd, fromChainClient, toChainClient, }) => {
114
+ const bridgePathway = (0, config_js_1.pathway)(bridgeKey, isProd, assetIn?.address);
115
+ if (!assetIn || !bridgePathway) {
116
+ return null;
117
+ }
118
+ const [, fromChain, toChain] = bridgeKey;
119
+ const assetInAddress = assetIn.address === viem_1.zeroAddress ? config_js_1.nativeAssetOut[fromChain] : assetIn.address;
120
+ const [toMappings, fromMappings] = await Promise.all([
121
+ (0, exports.links)({
122
+ chainId: Number(toChain),
123
+ target: bridgePathway.to,
124
+ address: assetInAddress,
125
+ client: toChainClient,
126
+ }),
127
+ (0, exports.links)({
128
+ chainId: Number(fromChain),
129
+ target: bridgePathway.from,
130
+ address: assetInAddress,
131
+ client: fromChainClient,
132
+ }),
133
+ ]);
134
+ const [toBridged, toNative] = toMappings;
135
+ if (toBridged !== viem_1.zeroAddress) {
136
+ return {
137
+ originationChainId: fromChain,
138
+ assetInAddress: assetInAddress,
139
+ assetOutAddress: toBridged,
140
+ toHome: {
141
+ home: toBridged,
142
+ foreign: assetInAddress,
143
+ },
144
+ };
145
+ }
146
+ if (toNative !== viem_1.zeroAddress) {
147
+ return {
148
+ originationChainId: toChain,
149
+ assetInAddress: assetInAddress,
150
+ assetOutAddress: toNative,
151
+ toForeign: {
152
+ home: toNative,
153
+ foreign: assetInAddress,
154
+ },
155
+ };
156
+ }
157
+ const [fromBridged, fromNative] = fromMappings;
158
+ if (fromNative !== viem_1.zeroAddress) {
159
+ return {
160
+ originationChainId: toChain,
161
+ assetInAddress: assetInAddress,
162
+ assetOutAddress: fromNative,
163
+ toHome: {
164
+ home: assetInAddress,
165
+ foreign: fromNative,
166
+ },
167
+ };
168
+ }
169
+ if (fromBridged !== viem_1.zeroAddress) {
170
+ return {
171
+ originationChainId: fromChain,
172
+ assetInAddress: assetInAddress,
173
+ assetOutAddress: fromBridged,
174
+ toForeign: {
175
+ foreign: fromBridged,
176
+ home: assetInAddress,
177
+ },
178
+ };
179
+ }
180
+ // the token has not been bridged yet
181
+ return {
182
+ originationChainId: toChain,
183
+ assetInAddress: assetInAddress,
184
+ assetOutAddress: null,
185
+ ...(bridgePathway.toHome
186
+ ? {
187
+ toHome: {
188
+ foreign: assetInAddress,
189
+ home: null,
190
+ },
191
+ }
192
+ : {
193
+ toForeign: {
194
+ foreign: null,
195
+ home: assetInAddress,
196
+ },
197
+ }),
198
+ };
199
+ };
200
+ exports.tokenBridgeInfo = tokenBridgeInfo;
201
+ /**
202
+ * Check the prices that each router offers for the given paths
203
+ * @param assetInAddress the address of the asset going into the bridge
204
+ * @param oneTokenInt the number of tokens to push into the bridge (before fees)
205
+ * @param chain the chain of the asset going into the bridge
206
+ * @param bridgeKey the bridge key
207
+ * @param blockNumber the block number to use for the price
208
+ * @param paths the paths to check
209
+ * @returns the prices as bigint for each path, hex whenever the price is not available
210
+ */
211
+ const readAmountOut = ({ amountIn, chain, paths, client, uniV2Router, }) => {
212
+ return (0, multicall_1.multicallRead)({
213
+ chain: chains_js_1.chainsMetadata[chain],
214
+ client,
215
+ abi: abis.univ2Router,
216
+ // pulsex router
217
+ // a chain with no router reads nothing, as lodash's flatMap over undefined did
218
+ calls: (uniV2Router ? [uniV2Router] : (config_js_1.uniV2Routers[chain] ?? [])).flatMap((target) => paths.map((path) => ({
219
+ functionName: 'getAmountsOut',
220
+ allowFailure: true,
221
+ args: [amountIn, path],
222
+ target,
223
+ }))),
224
+ });
225
+ };
226
+ /**
227
+ * 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
228
+ * @param bridgeKeyPartner - the bridge key partner
229
+ * @param assetOut - the asset out
230
+ * @param measurementToken - the measurement token
231
+ * @param fromChainClient - the from chain client
232
+ * @param toChainClient - the to chain client
233
+ * @param assetLink - the asset link
234
+ * @param amountIn - the amount in
235
+ * @param isProd - whether to use the production pathway
236
+ * @returns the price corrective
237
+ */
238
+ const fetchPriceCorrective = ({ bridgeKeyPartner, assetOut, measurementToken, fromChainClient, toChainClient, assetLink, amountIn, isProd, }) => {
239
+ return {
240
+ getPaymentToken: async () => {
241
+ // fetch the token bridge info for the token that is about to be spent by the delivery service
242
+ return await (0, exports.tokenBridgeInfo)({
243
+ bridgeKey: bridgeKeyPartner,
244
+ assetIn: {
245
+ ...assetOut,
246
+ address: measurementToken,
247
+ },
248
+ isProd,
249
+ // clients are reversed here because we are actually fetching the
250
+ // tokens going the opposite direction to the provided bridge key
251
+ fromChainClient: toChainClient,
252
+ toChainClient: fromChainClient,
253
+ });
254
+ },
255
+ getSwapResults: async ({ paymentTokenResult, chain, uniV2Router, client, }) => {
256
+ return await Promise.all([
257
+ readAmountOut({
258
+ amountIn,
259
+ chain,
260
+ uniV2Router,
261
+ client,
262
+ paths: [
263
+ // check the direct route
264
+ [assetLink.assetInAddress, paymentTokenResult.assetOutAddress],
265
+ // might have heavier liquidity going through the native asset on the home side
266
+ [assetLink.assetInAddress, config_js_1.nativeAssetOut[chain], paymentTokenResult.assetOutAddress],
267
+ ],
268
+ }),
269
+ readAmountOut({
270
+ amountIn,
271
+ chain,
272
+ uniV2Router,
273
+ client,
274
+ paths: [[assetOut.address, measurementToken]],
275
+ // only the direct route is available.
276
+ // might be able to create a whitelist for this at some point
277
+ }),
278
+ ]);
279
+ },
280
+ reduceResults: ({ results, oneToken, }) => {
281
+ const outputFromRouter = (result) => {
282
+ if (typeof result === 'string') {
283
+ // the router failed to return a result
284
+ return 0n;
285
+ }
286
+ if (!result.length) {
287
+ // the router returned an empty result
288
+ return 0n;
289
+ }
290
+ // the last element is the amount of the output token
291
+ const last = result[result.length - 1];
292
+ return (last * oneToken) / amountIn;
293
+ };
294
+ const max = (amountsOut) => {
295
+ return amountsOut
296
+ .filter((amount) => amount !== undefined)
297
+ .reduce((max, current) => (max < current ? current : max), 0n);
298
+ };
299
+ // could do with a refactor to unify the results
300
+ const [outputs, inputs] = results;
301
+ const outputAmounts = outputs.map(outputFromRouter);
302
+ const inputAmounts = inputs.map(outputFromRouter);
303
+ const outputToken = max(outputAmounts);
304
+ const inputToken = max(inputAmounts);
305
+ const result = outputToken && outputToken > 0n
306
+ ? inputToken && inputToken > outputToken && inputToken / outputToken === 1n
307
+ ? inputToken
308
+ : outputToken
309
+ : inputToken;
310
+ return result;
311
+ },
312
+ };
313
+ };
314
+ exports.fetchPriceCorrective = fetchPriceCorrective;
315
+ /**
316
+ * Read the smallest amount the bridge will accept for this asset on this pathway.
317
+ *
318
+ * THE ENTRY MEDIATOR DECIDES, so this always reads `pathway.from` on the chain
319
+ * the funds leave. `feeManager` says which side prices the transfer; it has
320
+ * never said which side validates the amount, and using it for both is what
321
+ * produced the defect this replaces.
322
+ *
323
+ * Both mediators keep a `minPerTx` under the same name, and for a token that
324
+ * originates on the entry chain the two sides usually hold the same number. That
325
+ * agreement is a coincidence of configuration - each side is separately
326
+ * governed, and both happen to apply one blanket default. It breaks outright for
327
+ * a token that originates on the far side, because the two mediators key their
328
+ * limits by different addresses. Wrapped Pulse entering from Ethereum is the
329
+ * live case: the entry mediator enforces 50,000, and the destination mediator
330
+ * answers 0 for that same address because it files that token under its
331
+ * PulseChain address instead. Reading the destination got both the chain and the
332
+ * token key wrong, and reported no floor where a real one stood.
333
+ * @param assetIn - the asset the sender holds, on the chain it leaves from
334
+ * @param pathway - the pathway, with any per-asset overrides already applied
335
+ * @param fromPublicClient - a client for the chain the funds leave
336
+ * @returns the smallest amount the entry mediator will accept
337
+ */
338
+ const minBridgeAmountIn = async ({ assetIn, pathway, fromPublicClient, }) => fromPublicClient.readContract({
339
+ abi: abis.inputBridge,
340
+ functionName: 'minPerTx',
341
+ args: [assetIn.address],
342
+ address: pathway.from,
343
+ });
344
+ exports.minBridgeAmountIn = minBridgeAmountIn;
345
+ /** get the symbol of the native asset, unwrap it if it needs to be */
346
+ const nativeSymbol = (asset, unwrap = false) => {
347
+ return asset
348
+ ? unwrap && asset.address === config_js_1.nativeAssetOut[(0, config_js_1.toChain)(asset.chainId)]
349
+ ? asset.symbol.slice(1)
350
+ : asset.symbol
351
+ : '';
352
+ };
353
+ exports.nativeSymbol = nativeSymbol;
354
+ /**
355
+ * Returns the Multicall3 contract for the client's chain.
356
+ * @param client - a client whose `chain` is one of {@link chainsMetadata}'s chains
357
+ * @returns the Multicall3 contract instance
358
+ * @throws when the client carries no chain, or the chain has no Multicall3 address
359
+ */
360
+ const chainMulticall = (client) => {
361
+ const chainId = client.chain?.id;
362
+ if (chainId === undefined) {
363
+ throw new Error('chainMulticall: the client has no chain configured');
364
+ }
365
+ const address = chains_js_1.chainsMetadata[(0, config_js_1.toChain)(chainId)]?.contracts?.multicall3?.address;
366
+ if (!address) {
367
+ throw new Error(`chainMulticall: no Multicall3 address known for chain ${chainId}`);
368
+ }
369
+ return (0, viem_1.getContract)({ abi: viem_1.multicall3Abi, client, address });
370
+ };
371
+ exports.chainMulticall = chainMulticall;
372
+ /**
373
+ * Load the bridge fees for the given pathway, from chain client, and to chain client
374
+ * @param pathway - the pathway
375
+ * @param fromChainClient - the from chain client
376
+ * @param toChainClient - the to chain client
377
+ * @returns the bridge fees
378
+ */
379
+ const loadBridgeFees = async ({ pathway, fromChainClient, toChainClient, }) => {
380
+ const multicall = pathway.feeManager === 'from' ? (0, exports.chainMulticall)(fromChainClient) : (0, exports.chainMulticall)(toChainClient);
381
+ const [feeManagerResponse] = await multicall.read.aggregate3([
382
+ [
383
+ {
384
+ allowFailure: false,
385
+ target: pathway[pathway.feeManager],
386
+ callData: (0, viem_1.encodeFunctionData)({
387
+ abi: abis.inputBridge,
388
+ functionName: 'feeManager',
389
+ }),
390
+ },
391
+ ],
392
+ ]);
393
+ const { success, returnData } = feeManagerResponse;
394
+ if (!success) {
395
+ throw new Error('unable to load feeManager');
396
+ }
397
+ if (returnData === '0x') {
398
+ throw new Error('unable to read feeManager');
399
+ }
400
+ const feeManager = (returnData.startsWith('0x000000000000000000000000')
401
+ ? `0x${returnData.slice(26)}`
402
+ : `0x${returnData.slice(-40)}`);
403
+ const [keyH2F, keyF2H] = await multicall.read.aggregate3([
404
+ [
405
+ {
406
+ allowFailure: false,
407
+ target: feeManager,
408
+ callData: (0, viem_1.encodeFunctionData)({
409
+ abi: abis.feeManager,
410
+ functionName: 'HOME_TO_FOREIGN_FEE',
411
+ }),
412
+ },
413
+ {
414
+ allowFailure: false,
415
+ target: feeManager,
416
+ callData: (0, viem_1.encodeFunctionData)({
417
+ abi: abis.feeManager,
418
+ functionName: 'FOREIGN_TO_HOME_FEE',
419
+ }),
420
+ },
421
+ ],
422
+ ]);
423
+ const [feeH2F, feeF2H] = await multicall.read.aggregate3([
424
+ [
425
+ {
426
+ allowFailure: false,
427
+ target: feeManager,
428
+ callData: (0, viem_1.encodeFunctionData)({
429
+ abi: abis.feeManager,
430
+ functionName: 'getFee',
431
+ args: [keyH2F.returnData, viem_1.zeroAddress],
432
+ }),
433
+ },
434
+ {
435
+ allowFailure: false,
436
+ target: feeManager,
437
+ callData: (0, viem_1.encodeFunctionData)({
438
+ abi: abis.feeManager,
439
+ functionName: 'getFee',
440
+ args: [keyF2H.returnData, viem_1.zeroAddress],
441
+ }),
442
+ },
443
+ ],
444
+ ]);
445
+ const setting = {
446
+ feeManager,
447
+ feeH2F: BigInt(feeH2F.returnData),
448
+ feeF2H: BigInt(feeF2H.returnData),
449
+ };
450
+ return setting;
451
+ };
452
+ exports.loadBridgeFees = loadBridgeFees;
@@ -0,0 +1,160 @@
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
+ export declare const relayChainIds: {
22
+ /** Relay's chain id for Solana mainnet (virtual-machine type `svm`). */
23
+ readonly 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
+ readonly eclipse: 9286185;
36
+ /** Relay's chain id for Bitcoin mainnet (virtual-machine type `bvm`). */
37
+ readonly bitcoin: 8253038;
38
+ /** Relay's chain id for Tron mainnet (virtual-machine type `tvm`). */
39
+ readonly tron: 728126428;
40
+ /** Relay's chain id for The Open Network (virtual-machine type `tonvm`). */
41
+ readonly 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
+ readonly hyperliquid: 1337;
53
+ };
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
+ export declare const depositAddressChainIds: {
78
+ /** Zcash mainnet. SLIP-0044 coin type 133, hardened: 0x80000000 + 133. */
79
+ readonly zcash: 2147483781;
80
+ };
81
+ /**
82
+ * One member per pay-by-hand origin chain — the union every table keyed by a
83
+ * pay-by-hand chain must be typed against.
84
+ *
85
+ * WHY THIS UNION, NOT `number`. `DepositAddressDeposit`'s own doc says the same
86
+ * shape will serve Zcash, Dogecoin, Litecoin and the XRP Ledger alike, so a
87
+ * second member is coming. A table typed `Record<number, X>` or
88
+ * `Map<number, X>` accepts a member of {@link depositAddressChainIds} being
89
+ * missing silently; a table typed `Record<DepositAddressChain, X>` cannot
90
+ * compile until every member has an entry. The dangerous table this protects
91
+ * is the ecosystem lookup in `relay-quote.ts`: a miss there makes a pay-by-hand
92
+ * chain read as an Ethereum chain, which has a wallet, a signer and a
93
+ * transaction.
94
+ */
95
+ export type DepositAddressChain = keyof typeof depositAddressChainIds;
96
+ /**
97
+ * Whether a chain identifier names a chain this interface CANNOT SIGN ON.
98
+ *
99
+ * The one predicate every surface asks before offering a wallet. A chain that
100
+ * answers true has no connector, so anything that would connect, switch
101
+ * networks, estimate gas or compose a transaction for it is wrong — the reader
102
+ * is shown an address to pay instead.
103
+ *
104
+ * @param chainId - a chain identifier
105
+ * @returns whether the reader pays this chain by hand
106
+ */
107
+ export declare const isDepositAddressChain: (chainId: number) => boolean;
108
+ /**
109
+ * Display names for Relay's non-Ethereum origin chains.
110
+ *
111
+ * An ecosystem label is NOT a chain name, and using one as a name is actively
112
+ * wrong: `svm` holds both Solana and Eclipse, so labelling by ecosystem renders
113
+ * Eclipse as "Solana" — a different network, shown to someone choosing where
114
+ * their funds leave from. Keyed by chain id for exactly that reason.
115
+ */
116
+ export declare const relayChainNames: Map<number, string>;
117
+ /**
118
+ * Registers display names for chains this module does not know about.
119
+ *
120
+ * Call once during startup, before anything renders. Entries are merged, and a
121
+ * name declared in `virtualMachineChainNames` above WINS over a registered one:
122
+ * the local table is deliberate ("Binance Smart Chain", not the registry's
123
+ * "BNB Smart Chain"), and a registry that happens to disagree must not quietly
124
+ * rename a chain the product has already named.
125
+ *
126
+ * @param entries - chain id and display name pairs
127
+ */
128
+ export declare const registerChainNames: (entries: Iterable<readonly [number, string]>) => void;
129
+ /**
130
+ * Returns a human-readable chain name for the given chain id, covering both
131
+ * Ethereum-Virtual-Machine chains and Relay's non-Ethereum pseudo identifiers.
132
+ *
133
+ * Falls back to the numeric id stringified when the chain is not known — better
134
+ * to show "chain 999" than to silently drop the leg that traverses it.
135
+ *
136
+ * @param chainId - a decimal chain id, Relay's identifier included
137
+ * @returns the display name, or `chain <id>` when unknown
138
+ */
139
+ export declare const chainDisplayName: (chainId: number) => string;
140
+ /**
141
+ * The name this module KNOWS for a chain, or null when it knows none.
142
+ *
143
+ * Same lookup as {@link chainDisplayName} without the placeholder, so a caller
144
+ * with a better fallback of its own can reach one. {@link chainDisplayName} is
145
+ * defined in terms of this, which is the point: the two can never disagree
146
+ * about which chains are known.
147
+ *
148
+ * WHY A CALLER WOULD WANT THIS. The network chips in the token picker have a
149
+ * second name to fall back on — the aggregator's own chain list, which reaches
150
+ * chains this registry has never been told about and says "Unknown network"
151
+ * rather than printing a bare number. Choosing between the two used to be done
152
+ * by comparing `chainDisplayName`'s answer against the literal string
153
+ * `chain <id>`, which is a caller reaching into another function's fallback
154
+ * format: rename the placeholder here and that comparison quietly stops
155
+ * matching, leaving every unknown chain labelled with its number.
156
+ *
157
+ * @param chainId - a decimal chain id, Relay's identifiers included
158
+ * @returns the display name, or null when the chain is not known here
159
+ */
160
+ export declare const knownChainName: (chainId: number) => string | null;