@gibs/bridge-sdk 1.12.0 → 1.13.1

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 (118) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +234 -432
  3. package/dist/abis.d.ts +1 -0
  4. package/dist/bridge-limits.d.ts +103 -0
  5. package/dist/bridge-limits.js +84 -0
  6. package/dist/chain-info.d.ts +169 -0
  7. package/dist/chain-info.js +410 -0
  8. package/dist/chain-names.d.ts +160 -0
  9. package/dist/chain-names.js +200 -0
  10. package/dist/chains.d.ts +65 -0
  11. package/dist/chains.js +284 -0
  12. package/dist/config.d.ts +216 -0
  13. package/dist/config.js +493 -0
  14. package/dist/consolidated-quote.d.ts +554 -0
  15. package/dist/consolidated-quote.js +773 -0
  16. package/dist/destination-calldata.d.ts +118 -0
  17. package/dist/destination-calldata.js +152 -0
  18. package/dist/ecosystems.d.ts +217 -0
  19. package/dist/ecosystems.js +288 -0
  20. package/dist/fee-type.d.ts +10 -0
  21. package/dist/fee-type.js +9 -0
  22. package/dist/hyperliquid-execution.d.ts +152 -0
  23. package/dist/hyperliquid-execution.js +168 -0
  24. package/dist/image-links.d.ts +117 -0
  25. package/dist/image-links.js +142 -0
  26. package/dist/index.d.ts +20 -0
  27. package/dist/index.js +20 -0
  28. package/dist/lifi-execution-guard.d.ts +199 -0
  29. package/dist/lifi-execution-guard.js +400 -0
  30. package/dist/near-intents-conformance.d.ts +85 -0
  31. package/dist/near-intents-conformance.js +329 -0
  32. package/dist/near-intents-route.d.ts +47 -0
  33. package/dist/near-intents-route.js +265 -0
  34. package/dist/near-intents.d.ts +524 -0
  35. package/dist/near-intents.js +1055 -0
  36. package/dist/origin-deposit.d.ts +326 -0
  37. package/dist/origin-deposit.js +68 -0
  38. package/dist/pre-quote.d.ts +198 -0
  39. package/dist/pre-quote.js +175 -0
  40. package/dist/prices.d.ts +107 -0
  41. package/dist/prices.js +162 -0
  42. package/dist/providers.d.ts +221 -0
  43. package/dist/providers.js +157 -0
  44. package/dist/quote-fees.d.ts +102 -0
  45. package/dist/quote-fees.js +195 -0
  46. package/dist/referral.d.ts +77 -0
  47. package/dist/referral.js +72 -0
  48. package/dist/relay-currencies.d.ts +47 -0
  49. package/dist/relay-currencies.js +89 -0
  50. package/dist/relay-quote.d.ts +301 -0
  51. package/dist/relay-quote.js +983 -0
  52. package/dist/route-steps.d.ts +138 -0
  53. package/dist/route-steps.js +305 -0
  54. package/dist/routing/amounts.d.ts +80 -0
  55. package/dist/routing/amounts.js +120 -0
  56. package/dist/routing/candidate-route.d.ts +43 -0
  57. package/dist/routing/candidate-route.js +45 -0
  58. package/dist/routing/candidate.d.ts +237 -0
  59. package/dist/routing/candidate.js +96 -0
  60. package/dist/routing/carriers/ask-answer.d.ts +60 -0
  61. package/dist/routing/carriers/ask-answer.js +1 -0
  62. package/dist/routing/carriers/omnibridge.d.ts +137 -0
  63. package/dist/routing/carriers/omnibridge.js +419 -0
  64. package/dist/routing/carriers/pulsex.d.ts +149 -0
  65. package/dist/routing/carriers/pulsex.js +453 -0
  66. package/dist/routing/carriers/wrap.d.ts +25 -0
  67. package/dist/routing/carriers/wrap.js +115 -0
  68. package/dist/routing/composed-route-quality.d.ts +103 -0
  69. package/dist/routing/composed-route-quality.js +108 -0
  70. package/dist/routing/entry-chain-anchor.d.ts +88 -0
  71. package/dist/routing/entry-chain-anchor.js +55 -0
  72. package/dist/routing/format.d.ts +31 -0
  73. package/dist/routing/format.js +58 -0
  74. package/dist/routing/index.d.ts +34 -0
  75. package/dist/routing/index.js +42 -0
  76. package/dist/routing/producers.d.ts +770 -0
  77. package/dist/routing/producers.js +1564 -0
  78. package/dist/routing/providers.d.ts +26 -0
  79. package/dist/routing/providers.js +38 -0
  80. package/dist/routing/route-data.d.ts +355 -0
  81. package/dist/routing/route-data.js +1 -0
  82. package/dist/routing/search/compose.d.ts +168 -0
  83. package/dist/routing/search/compose.js +98 -0
  84. package/dist/routing/search/graph.d.ts +653 -0
  85. package/dist/routing/search/graph.js +445 -0
  86. package/dist/routing/search/plan-route-data.d.ts +244 -0
  87. package/dist/routing/search/plan-route-data.js +767 -0
  88. package/dist/routing/search/score.d.ts +353 -0
  89. package/dist/routing/search/score.js +427 -0
  90. package/dist/routing/usd-value.d.ts +17 -0
  91. package/dist/routing/usd-value.js +25 -0
  92. package/dist/settings.d.ts +692 -0
  93. package/dist/settings.js +909 -0
  94. package/dist/ton-execution.d.ts +117 -0
  95. package/dist/ton-execution.js +247 -0
  96. package/dist/tron-execution.d.ts +146 -0
  97. package/dist/tron-execution.js +239 -0
  98. package/dist/types.d.ts +51 -0
  99. package/dist/types.js +1 -0
  100. package/llms.txt +169 -0
  101. package/package.json +204 -23
  102. package/src/chain-info.test.ts +0 -968
  103. package/src/chain-info.ts +0 -498
  104. package/src/chains.test.ts +0 -123
  105. package/src/chains.ts +0 -88
  106. package/src/config.test.ts +0 -679
  107. package/src/config.ts +0 -500
  108. package/src/fee-type.test.ts +0 -45
  109. package/src/fee-type.ts +0 -14
  110. package/src/image-links.test.ts +0 -160
  111. package/src/image-links.ts +0 -65
  112. package/src/index.ts +0 -8
  113. package/src/settings.test.ts +0 -2754
  114. package/src/settings.ts +0 -875
  115. package/src/types.ts +0 -48
  116. package/tsconfig.json +0 -17
  117. package/vitest.config.ts +0 -13
  118. /package/{src/abis.ts → dist/abis.js} +0 -0
package/dist/config.js ADDED
@@ -0,0 +1,493 @@
1
+ import * as _ from 'lodash-es';
2
+ import { getAddress, isAddress, isAddressEqual, keccak256, stringToHex, zeroAddress, } from 'viem';
3
+ /**
4
+ * Add here your chain id as hex, be sure to add your chain in the chainsMetadata object too
5
+ */
6
+ export var Chains;
7
+ (function (Chains) {
8
+ Chains["PLS"] = "0x171";
9
+ Chains["ETH"] = "0x1";
10
+ Chains["BNB"] = "0x38";
11
+ // testnets
12
+ Chains["SEP"] = "0xaa36a7";
13
+ Chains["V4PLS"] = "0x3af";
14
+ // TBNB = '0x61',
15
+ })(Chains || (Chains = {}));
16
+ /** A map of chain ids to chain keys */
17
+ export const chainIdToKey = new Map(Object.entries(Chains).map(([key, chain]) => [chain, key]));
18
+ /**
19
+ * Converts a chain id to a chain key
20
+ * @param chainId - the chain id
21
+ * @returns the chain key
22
+ */
23
+ export const toChain = (chainId) => `0x${Number(chainId).toString(16)}`;
24
+ /**
25
+ * Converts a chain id to a chain key
26
+ * @param chainId - the chain id
27
+ * @returns the chain key
28
+ */
29
+ export const toChainKey = (chainId) => chainIdToKey.get(toChain(chainId));
30
+ // /** The provider of an omnibridge */
31
+ // export enum Provider {
32
+ // PULSECHAIN = 'pulsechain',
33
+ // TOKENSEX = 'tokensex',
34
+ // }
35
+ export const Providers = {
36
+ PULSECHAIN: 'pulsechain',
37
+ TOKENSEX: 'tokensex',
38
+ };
39
+ /** A map of chains to native asset out addresses */
40
+ export const nativeAssetOut = {
41
+ [Chains.ETH]: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
42
+ [Chains.BNB]: '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c',
43
+ [Chains.PLS]: '0xA1077a294dDE1B09bB078844df40758a5D0f9a27',
44
+ [Chains.SEP]: '0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9',
45
+ [Chains.V4PLS]: '0x70499adEBB11Efd915E3b69E700c331778628707',
46
+ };
47
+ /** A map of chains to deprecated native asset out addresses */
48
+ export const deprecatedNativeAssetOut = {
49
+ [Chains.PLS]: new Set(['0x97Ac4a2439A47c07ad535bb1188c989dae755341']),
50
+ };
51
+ /** A map of chains to uni v2 router addresses */
52
+ export const uniV2Routers = {
53
+ [Chains.PLS]: [
54
+ '0x98bf93ebf5c380C0e6Ae8e192A7e2AE08edAcc02',
55
+ '0x165C3410fC91EF562C50559f7d2289fEbed552d9',
56
+ ],
57
+ [Chains.ETH]: ['0x7a250d5630b4cf539739df2c5dacb4c659f2488d'],
58
+ [Chains.BNB]: ['0x05fF2B0DB69458A0750badebc4f9e13aDd608C7F'],
59
+ [Chains.SEP]: ['0xeE567Fe1712Faf6149d80dA1E6934E354124CfE3'],
60
+ [Chains.V4PLS]: [
61
+ '0xDaE9dd3d1A52CfCe9d5F2fAC7fDe164D500E50f7',
62
+ '0x636f6407B90661b73b1C0F7e24F4C79f624d0738',
63
+ ],
64
+ };
65
+ /**
66
+ * Each {@link uniV2Routers} entry's OWN factory address, same index, same
67
+ * chain — `router.factory()` read live from `one.valve.city` on 2026-09-24.
68
+ * Only PulseChain mainnet is filled: PulseX carries funds nowhere else
69
+ * (`routing/carriers/pulsex.ts`'s own `pulseXCarries`), so no other chain's
70
+ * factory has ever been needed or verified.
71
+ *
72
+ * MEASURED, NOT ASSUMED (owner Rule 13). Reading each factory's `getPair`
73
+ * and the resulting pool's `getReserves`, then recomputing `getAmountsOut`
74
+ * from the standard constant-product formula, showed the SAME fee ratio for
75
+ * both — `9971/10000` (0.29%) — to the base unit, on both a one-hop and a
76
+ * two-hop path. "V1 and V2 differ" was the assumption going in; measurement
77
+ * said otherwise, so `routing/carriers/pulsex.ts`'s `exact` uses one shared
78
+ * fee constant rather than two.
79
+ *
80
+ * `0x1715a3E4A142d8b698131108995174F37aEBA10D` (the V1 factory, index 0) is
81
+ * NOT a copy-paste of the omnibridge's Ethereum mediator address from
82
+ * `pathways` above — it is the same string on a DIFFERENT chain (PulseChain,
83
+ * not Ethereum), confirmed by reading it fresh from `one.valve.city/…/evm/369`.
84
+ * Two unrelated contracts landing on the same address on two different
85
+ * chains is possible (a shared deployer at a matching nonce, or a CREATE2
86
+ * salt collision) and worth this note so a future reader does not assume a
87
+ * transcription error and "fix" it back to something wrong.
88
+ */
89
+ export const uniV2Factories = {
90
+ [Chains.PLS]: [
91
+ '0x1715a3E4A142d8b698131108995174F37aEBA10D',
92
+ '0x29eA7545DEf87022BAdc76323F373EA1e707C523',
93
+ ],
94
+ [Chains.ETH]: [],
95
+ [Chains.BNB]: [],
96
+ [Chains.SEP]: [],
97
+ [Chains.V4PLS]: [],
98
+ };
99
+ /** A map of chains to native token symbols */
100
+ export const nativeTokenSymbol = {
101
+ [Chains.PLS]: 'PLS',
102
+ [Chains.V4PLS]: 'V4PLS',
103
+ [Chains.ETH]: 'ETH',
104
+ [Chains.SEP]: 'sepETH',
105
+ [Chains.BNB]: 'BNB',
106
+ };
107
+ /** A map of chains to native token names */
108
+ export const nativeTokenName = {
109
+ [Chains.PLS]: 'Pulse',
110
+ [Chains.V4PLS]: 'V4 Pulse',
111
+ [Chains.ETH]: 'Ether',
112
+ [Chains.SEP]: 'Sepolia Ether',
113
+ [Chains.BNB]: 'BNB',
114
+ };
115
+ /** The settings for the pulsechain pls eth pathway */
116
+ const pulsechainPLSETHSettings = {
117
+ from: '0x0e18d0d556b652794EF12Bf68B2dC857EF5f3996',
118
+ to: '0xe20E337DB2a00b1C37139c873B92a0AAd3F468bF',
119
+ destinationRouter: '0x1F0144Ce3BDaf11944Fe0beF6444599a0500695B',
120
+ nativeRouter: '0xE66877Cfe4CEc10ffBbBB3092B7001321AB5809D',
121
+ };
122
+ export const pathways = {
123
+ [Providers.PULSECHAIN]: {
124
+ [Chains.PLS]: {
125
+ [Chains.ETH]: {
126
+ from: '0x4fD0aaa7506f3d9cB8274bdB946Ec42A1b8751Ef',
127
+ to: '0x1715a3E4A142d8b698131108995174F37aEBA10D',
128
+ destinationRouter: '0x2Ed02372C3efF1F239B22a901ceA8Cf6fbf82d8d',
129
+ nativeRouter: '0x612Da68aA7BcA625dD2F27f252cddB573674991A',
130
+ validator: '0x5ECfE77502317F3677f23C3b8Ab17929ACE3D74E',
131
+ usesExtraParam: false,
132
+ feeManager: 'from',
133
+ toHome: false,
134
+ requiresDelivery: true,
135
+ // weth from ethereum on pulsechain
136
+ bridgedNativeAssetOut: '0x02DcdD04e3F455D838cd1249292C58f3B79e3C3C',
137
+ settingOverrides: {
138
+ [zeroAddress]: pulsechainPLSETHSettings,
139
+ [getAddress(nativeAssetOut[Chains.PLS])]: pulsechainPLSETHSettings,
140
+ },
141
+ },
142
+ },
143
+ [Chains.ETH]: {
144
+ [Chains.PLS]: {
145
+ from: '0x1715a3E4A142d8b698131108995174F37aEBA10D',
146
+ to: '0x4fD0aaa7506f3d9cB8274bdB946Ec42A1b8751Ef',
147
+ nativeRouter: '0x2Ed02372C3efF1F239B22a901ceA8Cf6fbf82d8d',
148
+ destinationRouter: '0x612Da68aA7BcA625dD2F27f252cddB573674991A',
149
+ validator: '0x5ECfE77502317F3677f23C3b8Ab17929ACE3D74E',
150
+ feeManager: 'to',
151
+ usesExtraParam: false,
152
+ toHome: true,
153
+ requiresDelivery: false,
154
+ // wpls from pulsechain on ethereum
155
+ bridgedNativeAssetOut: '0xA882606494D86804B5514E07e6Bd2D6a6eE6d68A',
156
+ settingOverrides: {
157
+ [getAddress('0xa882606494d86804b5514e07e6bd2d6a6ee6d68a')]: {
158
+ from: '0xe20E337DB2a00b1C37139c873B92a0AAd3F468bF',
159
+ to: '0x0e18d0d556b652794EF12Bf68B2dC857EF5f3996',
160
+ destinationRouter: '0xE66877Cfe4CEc10ffBbBB3092B7001321AB5809D',
161
+ nativeRouter: '0x1F0144Ce3BDaf11944Fe0beF6444599a0500695B',
162
+ },
163
+ },
164
+ },
165
+ },
166
+ },
167
+ [Providers.TOKENSEX]: {
168
+ [Chains.PLS]: {
169
+ [Chains.BNB]: {
170
+ from: '0xf1DFc63e10fF01b8c3d307529b47AefaD2154C0e',
171
+ to: '0xb4005881e81a6ecd2c1f75d58e8e41f28d59c6b1',
172
+ destinationRouter: '0x9c50EfD36dF2DBD310fBC981d6D8478cF3484B85',
173
+ nativeRouter: '0xB80B80EBB375BD83a9d6c0761b197d16a8670f81',
174
+ validator: '0xc3c3d5d3ba946a2eb3906878ebe187418b0b524e',
175
+ feeManager: 'from',
176
+ usesExtraParam: true,
177
+ toHome: false,
178
+ requiresDelivery: true,
179
+ // wbnb from bsc on pulsechain (tokensex)
180
+ bridgedNativeAssetOut: '0x518076CCE3729eF1a3877EA3647a26e278e764FE',
181
+ },
182
+ },
183
+ [Chains.BNB]: {
184
+ [Chains.PLS]: {
185
+ from: '0xb4005881e81a6ecd2c1f75d58e8e41f28d59c6b1',
186
+ to: '0xf1DFc63e10fF01b8c3d307529b47AefaD2154C0e',
187
+ nativeRouter: '0x9c50EfD36dF2DBD310fBC981d6D8478cF3484B85',
188
+ destinationRouter: '0xB80B80EBB375BD83a9d6c0761b197d16a8670f81',
189
+ validator: '0xc3c3d5d3ba946a2eb3906878ebe187418b0b524e',
190
+ feeManager: 'to',
191
+ usesExtraParam: true,
192
+ toHome: true,
193
+ requiresDelivery: false,
194
+ // wpls from pulsechain on bsc (tokensex)
195
+ bridgedNativeAssetOut: '0xF6088134D28eeBEF7128BA41FaDb2FCA0666c64C',
196
+ },
197
+ },
198
+ },
199
+ };
200
+ export const testnetPathways = {
201
+ [Providers.TOKENSEX]: {
202
+ // plsv4 to bnb home omnibridge: 0xfd0c07C376D27EA0E9fA64Ac5D2481439e36CF9C
203
+ // [Chains.BNB]: {
204
+ // [Chains.V4PLS]: {
205
+ // from: '0xDDf1b0CD7fb7AAA310c703C17995c6671F9DC806',
206
+ // to: '0xfd0c07C376D27EA0E9fA64Ac5D2481439e36CF9C',
207
+ // usesExtraParam: false,
208
+ // requiresDelivery: false,
209
+ // toHome: true,
210
+ // feeManager: 'to',
211
+ // defaultAssetIn: {
212
+ // chainId: 56,
213
+ // address: nativeAssetOut[Chains.TBNB],
214
+ // },
215
+ // },
216
+ // },
217
+ // [Chains.V4PLS]: {
218
+ // [Chains.BNB]: {
219
+ // from: '0xfd0c07C376D27EA0E9fA64Ac5D2481439e36CF9C',
220
+ // to: '0xDDf1b0CD7fb7AAA310c703C17995c6671F9DC806',
221
+ // },
222
+ // },
223
+ },
224
+ [Providers.PULSECHAIN]: {
225
+ [Chains.V4PLS]: {
226
+ [Chains.SEP]: {
227
+ from: '0x6B08a50865aDeCe6e3869D9AfbB316d0a0436B6c',
228
+ to: '0x546e37DAA15cdb82fd1a717E5dEEa4AF08D4349A',
229
+ nativeRouter: '0xCA1BDc038909038C4B3cbab0EA0ec3cC2839F106',
230
+ destinationRouter: '0xCb4057d7DA4CE521B93b71186DfE11f9FBC3e3b1',
231
+ validator: '0xDcd4D88552c86114b2ca029F7F8d4e1a7951d051',
232
+ usesExtraParam: false,
233
+ requiresDelivery: true,
234
+ toHome: false,
235
+ feeManager: 'from',
236
+ bridgedNativeAssetOut: '0x3677bd78ccf4d299328ecfba61790cf8dbfcf686',
237
+ },
238
+ },
239
+ [Chains.SEP]: {
240
+ [Chains.V4PLS]: {
241
+ from: '0x546e37DAA15cdb82fd1a717E5dEEa4AF08D4349A',
242
+ to: '0x6B08a50865aDeCe6e3869D9AfbB316d0a0436B6c',
243
+ nativeRouter: '0xCb4057d7DA4CE521B93b71186DfE11f9FBC3e3b1',
244
+ destinationRouter: '0xCA1BDc038909038C4B3cbab0EA0ec3cC2839F106',
245
+ validator: '0xDcd4D88552c86114b2ca029F7F8d4e1a7951d051',
246
+ usesExtraParam: false,
247
+ requiresDelivery: false,
248
+ toHome: true,
249
+ feeManager: 'to',
250
+ bridgedNativeAssetOut: '0x35807560aD0597E23F452cdc82D4Fb0e7E3c6590',
251
+ },
252
+ },
253
+ },
254
+ };
255
+ /** The mainnet bridge keys */
256
+ const mainnetBridgeKeys = [
257
+ [Providers.PULSECHAIN, Chains.PLS, Chains.ETH],
258
+ [Providers.PULSECHAIN, Chains.ETH, Chains.PLS],
259
+ [Providers.TOKENSEX, Chains.PLS, Chains.BNB],
260
+ [Providers.TOKENSEX, Chains.BNB, Chains.PLS],
261
+ ];
262
+ /** The testnet bridge keys */
263
+ const testnetBridgeKeys = [
264
+ [Providers.PULSECHAIN, Chains.SEP, Chains.V4PLS],
265
+ [Providers.PULSECHAIN, Chains.V4PLS, Chains.SEP],
266
+ ];
267
+ /** Returns the valid bridge keys for the given is prod */
268
+ export const validBridgeKeys = (isProd) => [
269
+ ...mainnetBridgeKeys,
270
+ ...(isProd ? [] : testnetBridgeKeys),
271
+ ];
272
+ /** Every chain that appears only on a testnet pathway. */
273
+ const testnetChains = new Set(testnetBridgeKeys.flatMap(([, fromChain, toChain]) => [fromChain, toChain]));
274
+ /**
275
+ * Whether a chain belongs to the testnet pathway map rather than the mainnet one.
276
+ * @param chain - the chain to classify
277
+ * @returns true for Sepolia and PulseChain testnet V4
278
+ */
279
+ export const isTestnetChain = (chain) => testnetChains.has(chain);
280
+ /**
281
+ * Infers the bridge key from the current key, provider, from chain, and to chain.
282
+ *
283
+ * A chain the provider does not serve falls back to the provider's first chain,
284
+ * so a provider switch lands on a real pathway. That fallback never crosses
285
+ * between the testnet and mainnet maps: when testnets are off and a requested
286
+ * chain is a testnet chain, this returns null rather than a mainnet key for a
287
+ * testnet pair.
288
+ *
289
+ * @param options.currentKey - the current bridge key
290
+ * @param options.provider - the provider
291
+ * @param options.fromChain - the from chain (defaults to the current key's)
292
+ * @param options.toChain - the to chain (defaults to the current key's)
293
+ * @param options.isProd - true leaves testnet pathways out (default false: both maps)
294
+ * @returns the inferred bridge key, or null when no pathway can honour the request
295
+ */
296
+ export const inferBridgeKey = ({ currentKey, provider, fromChain, toChain, isProd = false, }) => {
297
+ const [, fromChainKey, toChainKey] = currentKey;
298
+ const from = fromChain ?? fromChainKey;
299
+ const to = toChain ?? toChainKey;
300
+ if (isProd && (isTestnetChain(from) || isTestnetChain(to))) {
301
+ return null;
302
+ }
303
+ const network = isTestnetChain(from) ? testnetPathways : pathways;
304
+ const providerGroups = network[provider] ?? {};
305
+ const nextFromChain = providerGroups[from] ? from : Object.keys(providerGroups)[0];
306
+ if (!nextFromChain) {
307
+ return null;
308
+ }
309
+ const destinations = providerGroups[nextFromChain] ?? {};
310
+ const nextToChain = destinations[to] ? to : Object.keys(destinations)[0];
311
+ if (!nextToChain) {
312
+ return null;
313
+ }
314
+ return [provider, nextFromChain, nextToChain];
315
+ };
316
+ /**
317
+ * Returns the pathway for the given bridge key, is prod, and asset in address
318
+ * @param bridgeKey - the bridge key
319
+ * @param isProd - whether to use the production pathway
320
+ * @param assetInAddress - the asset in address
321
+ * @returns the pathway
322
+ */
323
+ /**
324
+ * The pathway group for one provider on one chain, honouring the testnet map.
325
+ *
326
+ * Exists because {@link pathway} already knew that testnet pathways live in a
327
+ * SECOND map and are only in play off production, while other callers reached
328
+ * straight into `pathways` and therefore could not see a testnet route at all.
329
+ * That is the sort of knowledge that has to live in one place: duplicated, one
330
+ * copy silently lags the other, and the symptom is a thrown "no pathway found"
331
+ * on a route the rest of the application considers perfectly valid.
332
+ *
333
+ * @param provider - the bridge provider
334
+ * @param chain - the chain being bridged FROM
335
+ * @param isProd - whether this is a production build; testnets are off when true
336
+ * @returns the group keyed by destination chain, or undefined when unknown
337
+ */
338
+ export const pathwayGroup = (provider, chain, isProd) => _.get(pathways, [provider, chain]) ||
339
+ (!isProd ? _.get(testnetPathways, [provider, chain]) : undefined);
340
+ export const pathway = (bridgeKey, isProd, assetInAddress) => {
341
+ if (!bridgeKey)
342
+ return;
343
+ let pathway = _.get(pathways, bridgeKey) || (!isProd ? _.get(testnetPathways, bridgeKey) : undefined);
344
+ if (assetInAddress) {
345
+ const addr = getAddress(assetInAddress);
346
+ if (pathway?.settingOverrides?.[addr]) {
347
+ pathway = {
348
+ ...pathway,
349
+ ...pathway.settingOverrides[addr],
350
+ };
351
+ }
352
+ }
353
+ return pathway;
354
+ };
355
+ /**
356
+ * Returns the default asset in for the given bridge key and is prod
357
+ * @param bridgeKey - the bridge key
358
+ * @param isProd - whether to use the production pathway
359
+ * @returns the default asset in
360
+ */
361
+ export const defaultAssetIn = ($bridgeKey, isProd) => {
362
+ if (!$bridgeKey)
363
+ return null;
364
+ const conf = pathway($bridgeKey, isProd);
365
+ const defaultAssetIn = _.get(conf, ['bridgedNativeAssetOut']);
366
+ return defaultAssetIn;
367
+ };
368
+ /**
369
+ * Returns whether the given asset is the native asset for the given bridge key.
370
+ *
371
+ * Never throws. A token whose address is not known yet (a {@link TokenOut} for a
372
+ * not-yet-bridged token), an address that is not a valid address, and a bridge
373
+ * key with no pathway each answer false.
374
+ *
375
+ * @param asset - the asset
376
+ * @param bridgeKey - the bridge key
377
+ * @param options - which pathway maps to read; see {@link PathwayLookupOptions}
378
+ * @returns whether the given asset is the native asset for the given bridge key
379
+ */
380
+ export const isNative = (asset, bridgeKey, options = {}) => {
381
+ if (!bridgeKey || !asset?.address || !isAddress(asset.address, { strict: false })) {
382
+ return false;
383
+ }
384
+ const path = pathway(bridgeKey, options.isProd ?? false);
385
+ if (!path) {
386
+ return false;
387
+ }
388
+ if (isAddressEqual(asset.address, path.bridgedNativeAssetOut)) {
389
+ return true;
390
+ }
391
+ const wrappedNative = nativeAssetOut[toChain(asset.chainId)];
392
+ const isGasTokenOrItsWrapper = isAddressEqual(asset.address, zeroAddress) ||
393
+ (!!wrappedNative && isAddressEqual(asset.address, wrappedNative));
394
+ return isGasTokenOrItsWrapper && !asset.name.includes(' from Pulsechain');
395
+ };
396
+ /**
397
+ * Returns whether the given asset is unwrappable for the given bridge key.
398
+ *
399
+ * Never throws: a missing or malformed address and a bridge key with no
400
+ * pathway each answer false.
401
+ *
402
+ * @param bridgeKey - the bridge key
403
+ * @param assetIn - the asset in
404
+ * @param options - which pathway maps to read; see {@link PathwayLookupOptions}
405
+ * @returns whether the given asset is unwrappable for the given bridge key
406
+ */
407
+ export const isUnwrappable = (bridgeKey, assetIn, options = {}) => {
408
+ if (!bridgeKey || !assetIn?.address || !isAddress(assetIn.address, { strict: false })) {
409
+ return false;
410
+ }
411
+ const path = pathway(bridgeKey, options.isProd ?? false);
412
+ if (!path) {
413
+ return false;
414
+ }
415
+ return isAddressEqual(path.bridgedNativeAssetOut, assetIn.address);
416
+ };
417
+ /**
418
+ * Returns whether the given asset can be unwrapped for the given bridge key
419
+ * @param bridgeKey - the bridge key
420
+ * @param assetIn - the asset in
421
+ * @param options - which pathway maps to read; see {@link PathwayLookupOptions}
422
+ * @returns boolean
423
+ */
424
+ export const canChangeUnwrap = (bridgeKey, assetIn, options = {}) => {
425
+ return !!assetIn && isUnwrappable(bridgeKey, assetIn, options);
426
+ };
427
+ export const chains = {
428
+ ethereum: 1,
429
+ bsc: 56,
430
+ pulsechain: 369,
431
+ pulsechainV4: 943,
432
+ sepolia: 11155111,
433
+ };
434
+ export const chainIds = Object.values(chains);
435
+ /** Start blocks aligned with when bridge validators began operating — canonical reference for all ponder indexers in this monorepo. */
436
+ export const startBlocks = {
437
+ ethereum: 17_264_119,
438
+ bsc: 28_987_313,
439
+ pulsechain: 17_268_300,
440
+ pulsechainV4: 16_564_233,
441
+ sepolia: 3_331_901,
442
+ };
443
+ // provider -> home -> foreign
444
+ export const bridgeConfigs = {
445
+ [Providers.PULSECHAIN]: {
446
+ [chains.pulsechain]: {
447
+ [chains.ethereum]: [
448
+ {
449
+ pair: 'mainnet',
450
+ key: 'erc20',
451
+ home: '0x4fD0aaa7506f3d9cB8274bdB946Ec42A1b8751Ef',
452
+ foreign: '0x1715a3e4a142d8b698131108995174f37aeba10d',
453
+ },
454
+ {
455
+ pair: 'mainnet',
456
+ key: 'native',
457
+ home: '0x0e18d0d556b652794EF12Bf68B2dC857EF5f3996',
458
+ foreign: '0xe20E337DB2a00b1C37139c873B92a0AAd3F468bF',
459
+ },
460
+ ],
461
+ },
462
+ [chains.pulsechainV4]: {
463
+ [chains.sepolia]: [
464
+ {
465
+ pair: 'v4',
466
+ key: 'erc20',
467
+ home: '0x6B08a50865aDeCe6e3869D9AfbB316d0a0436B6c',
468
+ foreign: '0x546e37DAA15cdb82fd1a717E5dEEa4AF08D4349A',
469
+ },
470
+ {
471
+ pair: 'v4',
472
+ key: 'native',
473
+ home: '0x81c10846F40fA2B173FC47958D0a892529983F50',
474
+ foreign: '0x5e238ef968467cf443ef5ecb683b76c5a04a0421',
475
+ },
476
+ ],
477
+ },
478
+ },
479
+ [Providers.TOKENSEX]: {
480
+ [chains.pulsechain]: {
481
+ [chains.bsc]: [
482
+ {
483
+ pair: 'bsctokensex',
484
+ key: 'erc20',
485
+ home: '0xf1DFc63e10fF01b8c3d307529b47AefaD2154C0e',
486
+ foreign: '0xb4005881e81a6ecd2c1f75d58e8e41f28d59c6b1',
487
+ },
488
+ ],
489
+ },
490
+ },
491
+ };
492
+ export const HOME_TO_FOREIGN_FEE = keccak256(stringToHex('homeToForeignFee'));
493
+ export const FOREIGN_TO_HOME_FEE = keccak256(stringToHex('foreignToHomeFee'));