@gibs/bridge-sdk 1.13.1 → 1.18.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 (228) hide show
  1. package/README.md +295 -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 +255 -0
  28. package/dist/cjs/config.js +569 -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 +359 -0
  36. package/dist/cjs/execution.js +495 -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 +24 -0
  44. package/dist/cjs/index.js +40 -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 +117 -0
  59. package/dist/cjs/prices.js +224 -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/carrier-provider-key.d.ts +31 -0
  81. package/dist/cjs/routing/carrier-provider-key.js +42 -0
  82. package/dist/cjs/routing/carriers/ask-answer.d.ts +77 -0
  83. package/dist/cjs/routing/carriers/ask-answer.js +2 -0
  84. package/dist/cjs/routing/carriers/omnibridge.d.ts +137 -0
  85. package/dist/cjs/routing/carriers/omnibridge.js +459 -0
  86. package/dist/cjs/routing/carriers/pulsex-paths.d.ts +80 -0
  87. package/dist/cjs/routing/carriers/pulsex-paths.js +97 -0
  88. package/dist/cjs/routing/carriers/pulsex-split.d.ts +175 -0
  89. package/dist/cjs/routing/carriers/pulsex-split.js +193 -0
  90. package/dist/cjs/routing/carriers/pulsex.d.ts +184 -0
  91. package/dist/cjs/routing/carriers/pulsex.js +615 -0
  92. package/dist/cjs/routing/carriers/wrap.d.ts +25 -0
  93. package/dist/cjs/routing/carriers/wrap.js +119 -0
  94. package/dist/cjs/routing/composed-route-quality.d.ts +125 -0
  95. package/dist/cjs/routing/composed-route-quality.js +144 -0
  96. package/dist/cjs/routing/entry-chain-anchor.d.ts +88 -0
  97. package/dist/cjs/routing/entry-chain-anchor.js +59 -0
  98. package/dist/cjs/routing/format.d.ts +31 -0
  99. package/dist/cjs/routing/format.js +64 -0
  100. package/dist/cjs/routing/index.d.ts +42 -0
  101. package/dist/cjs/routing/index.js +142 -0
  102. package/dist/cjs/routing/producers.d.ts +770 -0
  103. package/dist/cjs/routing/producers.js +1617 -0
  104. package/dist/cjs/routing/providers.d.ts +31 -0
  105. package/dist/cjs/routing/providers.js +48 -0
  106. package/dist/cjs/routing/route-data.d.ts +397 -0
  107. package/dist/cjs/routing/route-data.js +2 -0
  108. package/dist/cjs/routing/search/compose.d.ts +168 -0
  109. package/dist/cjs/routing/search/compose.js +104 -0
  110. package/dist/cjs/routing/search/graph.d.ts +668 -0
  111. package/dist/cjs/routing/search/graph.js +461 -0
  112. package/dist/cjs/routing/search/plan-route-data.d.ts +285 -0
  113. package/dist/cjs/routing/search/plan-route-data.js +871 -0
  114. package/dist/cjs/routing/search/score.d.ts +356 -0
  115. package/dist/cjs/routing/search/score.js +445 -0
  116. package/dist/cjs/routing/swap-transactions.d.ts +95 -0
  117. package/dist/cjs/routing/swap-transactions.js +133 -0
  118. package/dist/cjs/routing/usd-value.d.ts +17 -0
  119. package/dist/cjs/routing/usd-value.js +29 -0
  120. package/dist/cjs/settings.d.ts +785 -0
  121. package/dist/cjs/settings.js +1074 -0
  122. package/dist/cjs/swap-venues.d.ts +43 -0
  123. package/dist/cjs/swap-venues.js +29 -0
  124. package/dist/cjs/ton-connect.d.ts +98 -0
  125. package/dist/cjs/ton-connect.js +206 -0
  126. package/dist/cjs/ton-execution.d.ts +7 -0
  127. package/dist/cjs/ton-execution.js +23 -0
  128. package/dist/cjs/ton.d.ts +37 -0
  129. package/dist/cjs/ton.js +83 -0
  130. package/dist/cjs/tron-execution.d.ts +146 -0
  131. package/dist/cjs/tron-execution.js +248 -0
  132. package/dist/cjs/types.d.ts +51 -0
  133. package/dist/cjs/types.js +2 -0
  134. package/dist/claims.d.ts +198 -0
  135. package/dist/claims.js +140 -0
  136. package/dist/config.d.ts +42 -3
  137. package/dist/config.js +87 -21
  138. package/dist/consolidated-quote.d.ts +109 -15
  139. package/dist/consolidated-quote.js +310 -52
  140. package/dist/execution.d.ts +359 -0
  141. package/dist/execution.js +455 -0
  142. package/dist/hyperliquid-execution.js +2 -3
  143. package/dist/index.d.ts +4 -0
  144. package/dist/index.js +4 -0
  145. package/dist/lifi-execution-guard.d.ts +13 -2
  146. package/dist/lifi-execution-guard.js +4 -0
  147. package/dist/near-intents.js +2 -3
  148. package/dist/pre-quote.d.ts +6 -6
  149. package/dist/pre-quote.js +10 -14
  150. package/dist/prices.d.ts +10 -0
  151. package/dist/prices.js +52 -1
  152. package/dist/providers.d.ts +17 -0
  153. package/dist/providers.js +6 -0
  154. package/dist/referral.d.ts +12 -4
  155. package/dist/referral.js +12 -4
  156. package/dist/relay-depository.d.ts +2 -0
  157. package/dist/relay-depository.js +82 -0
  158. package/dist/relay-quote.js +2 -3
  159. package/dist/routing/candidate.d.ts +3 -3
  160. package/dist/routing/candidate.js +3 -3
  161. package/dist/routing/carrier-provider-key.d.ts +31 -0
  162. package/dist/routing/carrier-provider-key.js +37 -0
  163. package/dist/routing/carriers/ask-answer.d.ts +17 -0
  164. package/dist/routing/carriers/omnibridge.js +23 -21
  165. package/dist/routing/carriers/pulsex-paths.d.ts +80 -0
  166. package/dist/routing/carriers/pulsex-paths.js +92 -0
  167. package/dist/routing/carriers/pulsex-split.d.ts +175 -0
  168. package/dist/routing/carriers/pulsex-split.js +185 -0
  169. package/dist/routing/carriers/pulsex.d.ts +81 -46
  170. package/dist/routing/carriers/pulsex.js +267 -148
  171. package/dist/routing/composed-route-quality.d.ts +28 -6
  172. package/dist/routing/composed-route-quality.js +36 -5
  173. package/dist/routing/entry-chain-anchor.d.ts +1 -1
  174. package/dist/routing/entry-chain-anchor.js +1 -1
  175. package/dist/routing/index.d.ts +11 -3
  176. package/dist/routing/index.js +8 -2
  177. package/dist/routing/producers.js +1 -1
  178. package/dist/routing/providers.d.ts +5 -0
  179. package/dist/routing/providers.js +5 -0
  180. package/dist/routing/route-data.d.ts +47 -5
  181. package/dist/routing/search/graph.d.ts +15 -0
  182. package/dist/routing/search/plan-route-data.d.ts +42 -1
  183. package/dist/routing/search/plan-route-data.js +68 -9
  184. package/dist/routing/search/score.d.ts +3 -0
  185. package/dist/routing/search/score.js +11 -3
  186. package/dist/routing/swap-transactions.d.ts +95 -0
  187. package/dist/routing/swap-transactions.js +127 -0
  188. package/dist/settings.d.ts +94 -1
  189. package/dist/settings.js +95 -3
  190. package/dist/swap-venues.d.ts +43 -0
  191. package/dist/swap-venues.js +24 -0
  192. package/dist/ton-connect.d.ts +98 -0
  193. package/dist/ton-connect.js +200 -0
  194. package/dist/ton-execution.d.ts +4 -114
  195. package/dist/ton-execution.js +4 -244
  196. package/dist/ton.d.ts +37 -0
  197. package/dist/ton.js +65 -0
  198. package/docs/examples/example-a-ether-to-pulse.ts +300 -0
  199. package/docs/examples/example-b-token-pulsechain-to-ethereum.ts +270 -0
  200. package/docs/examples/shared.ts +261 -0
  201. package/docs/examples/tsconfig.json +18 -0
  202. package/docs/integration-guide.md +617 -0
  203. package/ecosystems/package.json +6 -0
  204. package/execution/package.json +6 -0
  205. package/fee-type/package.json +6 -0
  206. package/hyperliquid-execution/package.json +6 -0
  207. package/image-links/package.json +6 -0
  208. package/lifi-execution-guard/package.json +6 -0
  209. package/llms.txt +75 -10
  210. package/near-intents/package.json +6 -0
  211. package/near-intents-route/package.json +6 -0
  212. package/origin-deposit/package.json +6 -0
  213. package/package.json +817 -10
  214. package/pre-quote/package.json +6 -0
  215. package/prices/package.json +6 -0
  216. package/providers/package.json +6 -0
  217. package/quote-fees/package.json +6 -0
  218. package/referral/package.json +6 -0
  219. package/relay-currencies/package.json +6 -0
  220. package/relay-quote/package.json +6 -0
  221. package/route-steps/package.json +6 -0
  222. package/routing/package.json +6 -0
  223. package/settings/package.json +6 -0
  224. package/ton/package.json +6 -0
  225. package/ton-connect/package.json +6 -0
  226. package/ton-execution/package.json +6 -0
  227. package/tron-execution/package.json +6 -0
  228. package/types/package.json +6 -0
package/dist/claims.js ADDED
@@ -0,0 +1,140 @@
1
+ import { encodeFunctionData, isHex, numberToHex } from 'viem';
2
+ import * as abis from './abis.js';
3
+ const strip0x = (input) => input.replace(/^0x/, '');
4
+ /**
5
+ * Splits one 65-byte validator signature into its `v`, `r` and `s` parts.
6
+ *
7
+ * @param rawSignature - the signature as the indexer stores it, with or without a `0x` prefix
8
+ * @returns the three parts, hex without prefixes
9
+ */
10
+ export const signatureToVRS = (rawSignature) => {
11
+ const signature = strip0x(rawSignature);
12
+ const word = 32;
13
+ const word2 = word * 2;
14
+ const word4 = word2 * 2;
15
+ const r = signature.slice(0, word2);
16
+ const s = signature.slice(word2, word4);
17
+ const v = signature.slice(word4);
18
+ return { v, r, s };
19
+ };
20
+ /**
21
+ * Packs signatures in the layout the bridge's `executeSignatures` reads: one
22
+ * count byte, then every `v`, then every `r`, then every `s`.
23
+ *
24
+ * @param signatures - the split signatures, in the order the validators signed
25
+ * @returns the packed signatures as one hex string
26
+ */
27
+ export const packSignatures = (signatures) => {
28
+ const length = strip0x(numberToHex(signatures.length));
29
+ const countByte = length.length === 1 ? `0${length}` : length;
30
+ const v = signatures.map((signature) => signature.v).join('');
31
+ const r = signatures.map((signature) => signature.r).join('');
32
+ const s = signatures.map((signature) => signature.s).join('');
33
+ return `0x${countByte}${v}${r}${s}`;
34
+ };
35
+ /**
36
+ * The calldata for a release that pays no delivery tip: a direct call to the
37
+ * destination bridge.
38
+ *
39
+ * @param options.encodedData - the bridge message, `UserRequest.encodedData`
40
+ * @param options.encodedSignatures - the output of {@link packSignatures}
41
+ * @returns the calldata for `safeExecuteSignaturesWithAutoGasLimit`
42
+ */
43
+ export const encodeReleaseWithoutTipData = ({ encodedData, encodedSignatures, }) => encodeFunctionData({
44
+ abi: abis.relayTokensDirect,
45
+ functionName: 'safeExecuteSignaturesWithAutoGasLimit',
46
+ args: [encodedData, encodedSignatures],
47
+ });
48
+ /**
49
+ * The calldata for a release sent through the pathway's destination output
50
+ * router, the path a fee-director (delivery) request uses.
51
+ *
52
+ * @param options.validator - the pathway's validator contract
53
+ * @param options.encodedData - the bridge message, `UserRequest.encodedData`
54
+ * @param options.encodedSignatures - the output of {@link packSignatures}
55
+ * @returns the calldata for the router's `safeExecuteSignaturesWithAutoGasLimit`
56
+ */
57
+ export const encodeReleaseToRouterData = ({ validator, encodedData, encodedSignatures, }) => encodeFunctionData({
58
+ abi: abis.outputRouter,
59
+ functionName: 'safeExecuteSignaturesWithAutoGasLimit',
60
+ args: [validator, encodedData, encodedSignatures],
61
+ });
62
+ /**
63
+ * The one place a claim's target and calldata come from. The interface's
64
+ * release hook and {@link buildClaimTransaction} both call it.
65
+ *
66
+ * @param options.encodedData - the bridge message
67
+ * @param options.signatures - the raw validator signatures, in signing order
68
+ * @param options.destinationAmbAddress - the destination bridge, used by the `direct` route
69
+ * @param options.via - which contract receives the claim
70
+ * @returns the target contract and the calldata
71
+ */
72
+ export const claimCall = ({ encodedData, signatures, destinationAmbAddress, via, }) => {
73
+ const encodedSignatures = packSignatures(signatures.map(signatureToVRS));
74
+ if (via.kind === 'router') {
75
+ return {
76
+ to: via.destinationRouter,
77
+ data: encodeReleaseToRouterData({ validator: via.validator, encodedData, encodedSignatures }),
78
+ };
79
+ }
80
+ return { to: destinationAmbAddress, data: encodeReleaseWithoutTipData({ encodedData, encodedSignatures }) };
81
+ };
82
+ const isSignatureList = (value) => Array.isArray(value) && value.every((entry) => typeof entry === 'string' && isHex(entry));
83
+ const refused = (refusal) => ({ kind: 'refused', refusal });
84
+ /**
85
+ * Builds the manual-claim transaction for one bridge request, or refuses with
86
+ * a typed reason.
87
+ *
88
+ * The checks run in this order: request type, delivery, signing, then the
89
+ * stored signature count. A delivered request is refused before the signing
90
+ * check, because delivery also sets `finishedSigning`.
91
+ *
92
+ * ASSUMPTION: the signatures are only complete when every validator sent
93
+ * `submitSignature` directly to the home bridge. The indexer drops a
94
+ * signature sent any other way; see this module's head note. This builder
95
+ * catches the drop by comparing the stored list with the required-signature
96
+ * threshold, or with `confirmedSignatures` when the record carries no threshold.
97
+ *
98
+ * @param options.request - the indexer's `UserRequest` record
99
+ * @param options.via - the claim target; see {@link ClaimRoute}
100
+ * @returns a `claim` plan whose transaction runs on the destination chain, or a refusal
101
+ */
102
+ export const buildClaimTransaction = ({ request, via, }) => {
103
+ if (request.type !== 'signature')
104
+ return refused({ reason: 'wrong-type', type: request.type });
105
+ if (request.delivered)
106
+ return refused({ reason: 'already-delivered' });
107
+ if (!request.finishedSigning)
108
+ return refused({ reason: 'not-signed-yet' });
109
+ if (!isSignatureList(request.signatures))
110
+ return refused({ reason: 'malformed-request', field: 'signatures' });
111
+ if (!isHex(request.encodedData))
112
+ return refused({ reason: 'malformed-request', field: 'encodedData' });
113
+ if (!isHex(request.destinationAmbAddress)) {
114
+ return refused({ reason: 'malformed-request', field: 'destinationAmbAddress' });
115
+ }
116
+ const needed = Number(request.requiredSignatures?.value ?? request.confirmedSignatures);
117
+ const stored = request.signatures.length;
118
+ if (stored < needed)
119
+ return refused({ reason: 'signatures-incomplete', stored, needed });
120
+ const { to, data } = claimCall({
121
+ encodedData: request.encodedData,
122
+ signatures: request.signatures,
123
+ destinationAmbAddress: request.destinationAmbAddress,
124
+ via,
125
+ });
126
+ return {
127
+ kind: 'claim',
128
+ transaction: {
129
+ chainId: Number(request.destinationChainId),
130
+ kind: 'claim',
131
+ to,
132
+ data,
133
+ value: 0n,
134
+ // The calldata itself asks the bridge to pick its own gas limit
135
+ // (`safeExecuteSignaturesWithAutoGasLimit`); the wallet estimates the rest.
136
+ gasLimit: null,
137
+ waitForReceipt: false,
138
+ },
139
+ };
140
+ };
package/dist/config.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { type Hex } from 'viem';
2
+ import type { SwapVenues } from './swap-venues.js';
2
3
  import type { BridgeKey, Token, TokenOut } from './types.js';
3
4
  /**
4
5
  * Add here your chain id as hex, be sure to add your chain in the chainsMetadata object too
@@ -33,10 +34,48 @@ export declare const Providers: {
33
34
  export type Provider = (typeof Providers)[keyof typeof Providers];
34
35
  /** A map of chains to native asset out addresses */
35
36
  export declare const nativeAssetOut: Record<Chains, Hex>;
37
+ /**
38
+ * Four PulseChain mainnet tokens that no other constant in this package
39
+ * names. The PulseX carrier routes swaps through them
40
+ * (`routing/carriers/pulsex-paths.ts`), and the interface builds its
41
+ * PulseChain hub nodes from the two stablecoins.
42
+ *
43
+ * Each address was already in the repository before it moved here: USDC and
44
+ * USDT from the interface's `HUB_STABLECOIN_ADDRESSES`
45
+ * (`packages/ui/src/lib/state/useRouteSearch.ts`), PLSX and HEX from
46
+ * `scripts/route-parity-corpus.ts`. Each one was read on chain again on
47
+ * 2026-10-06 (`symbol()`, `decimals()`): PLSX 18, HEX 8, USDC 6, USDT 6.
48
+ * `getAddress` checksums them at load, so a mistyped character fails the
49
+ * build rather than silently matching nothing.
50
+ */
51
+ export declare const pulsechainTokenAddresses: Readonly<{
52
+ /** PulseX, the exchange's own token. */
53
+ PLSX: `0x${string}`;
54
+ /** HEX. */
55
+ HEX: `0x${string}`;
56
+ /** USD Coin, bridged from Ethereum. */
57
+ USDC: `0x${string}`;
58
+ /** Tether USD, bridged from Ethereum. */
59
+ USDT: `0x${string}`;
60
+ }>;
36
61
  /** A map of chains to deprecated native asset out addresses */
37
62
  export declare const deprecatedNativeAssetOut: Partial<Record<Chains, Set<Hex>>>;
38
- /** A map of chains to uni v2 router addresses */
39
- export declare const uniV2Routers: Record<Chains, Hex[]>;
63
+ /**
64
+ * The swap venues the package ships with: PulseX V1 then V2 on PulseChain.
65
+ * Frozen. A caller who wants other routers passes its own
66
+ * {@link SwapVenues} (see `resolveSwapVenues`); this table is never mutated.
67
+ *
68
+ * Each factory is the router's own `router.factory()` read on chain — see
69
+ * {@link uniV2Factories}'s doc. The fee is 29 basis points for both
70
+ * deployments (measured, same doc).
71
+ */
72
+ export declare const defaultSwapVenues: SwapVenues;
73
+ /**
74
+ * A map of chains to uni v2 router addresses. Frozen. PulseChain's entries
75
+ * derive from {@link defaultSwapVenues}, so the two cannot drift. Kept for
76
+ * compatibility; to swap on other routers pass `swapVenues` instead.
77
+ */
78
+ export declare const uniV2Routers: Readonly<Record<Chains, readonly Hex[]>>;
40
79
  /**
41
80
  * Each {@link uniV2Routers} entry's OWN factory address, same index, same
42
81
  * chain — `router.factory()` read live from `one.valve.city` on 2026-09-24.
@@ -61,7 +100,7 @@ export declare const uniV2Routers: Record<Chains, Hex[]>;
61
100
  * salt collision) and worth this note so a future reader does not assume a
62
101
  * transcription error and "fix" it back to something wrong.
63
102
  */
64
- export declare const uniV2Factories: Record<Chains, Hex[]>;
103
+ export declare const uniV2Factories: Readonly<Record<Chains, readonly Hex[]>>;
65
104
  /** A map of chains to native token symbols */
66
105
  export declare const nativeTokenSymbol: Record<Chains, string>;
67
106
  /** A map of chains to native token names */
package/dist/config.js CHANGED
@@ -1,4 +1,3 @@
1
- import * as _ from 'lodash-es';
2
1
  import { getAddress, isAddress, isAddressEqual, keccak256, stringToHex, zeroAddress, } from 'viem';
3
2
  /**
4
3
  * Add here your chain id as hex, be sure to add your chain in the chainsMetadata object too
@@ -44,16 +43,41 @@ export const nativeAssetOut = {
44
43
  [Chains.SEP]: '0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9',
45
44
  [Chains.V4PLS]: '0x70499adEBB11Efd915E3b69E700c331778628707',
46
45
  };
46
+ /**
47
+ * Four PulseChain mainnet tokens that no other constant in this package
48
+ * names. The PulseX carrier routes swaps through them
49
+ * (`routing/carriers/pulsex-paths.ts`), and the interface builds its
50
+ * PulseChain hub nodes from the two stablecoins.
51
+ *
52
+ * Each address was already in the repository before it moved here: USDC and
53
+ * USDT from the interface's `HUB_STABLECOIN_ADDRESSES`
54
+ * (`packages/ui/src/lib/state/useRouteSearch.ts`), PLSX and HEX from
55
+ * `scripts/route-parity-corpus.ts`. Each one was read on chain again on
56
+ * 2026-10-06 (`symbol()`, `decimals()`): PLSX 18, HEX 8, USDC 6, USDT 6.
57
+ * `getAddress` checksums them at load, so a mistyped character fails the
58
+ * build rather than silently matching nothing.
59
+ */
60
+ export const pulsechainTokenAddresses = Object.freeze({
61
+ /** PulseX, the exchange's own token. */
62
+ PLSX: getAddress('0x95b303987a60c71504d99aa1b13b4da07b0790ab'),
63
+ /** HEX. */
64
+ HEX: getAddress('0x2b591e99afe9f32eaa6214f7b7629768c40eeb39'),
65
+ /** USD Coin, bridged from Ethereum. */
66
+ USDC: getAddress('0x15d38573d2feeb82e7ad5187ab8c1d52810b1f07'),
67
+ /** Tether USD, bridged from Ethereum. */
68
+ USDT: getAddress('0x0cb6f5a34ad42ec934882a05265a7d5f59b51a2f'),
69
+ });
47
70
  /** A map of chains to deprecated native asset out addresses */
48
71
  export const deprecatedNativeAssetOut = {
49
72
  [Chains.PLS]: new Set(['0x97Ac4a2439A47c07ad535bb1188c989dae755341']),
50
73
  };
51
- /** A map of chains to uni v2 router addresses */
52
- export const uniV2Routers = {
53
- [Chains.PLS]: [
54
- '0x98bf93ebf5c380C0e6Ae8e192A7e2AE08edAcc02',
55
- '0x165C3410fC91EF562C50559f7d2289fEbed552d9',
56
- ],
74
+ /**
75
+ * Routers on chains where this package knows the router but has not verified
76
+ * a factory, so no {@link SwapVenue} can be built for them. They stay in
77
+ * {@link uniV2Routers} for the native-price reads (`chain-info.ts`,
78
+ * `readAmountOut`) that need only a router.
79
+ */
80
+ const routersWithoutVenue = {
57
81
  [Chains.ETH]: ['0x7a250d5630b4cf539739df2c5dacb4c659f2488d'],
58
82
  [Chains.BNB]: ['0x05fF2B0DB69458A0750badebc4f9e13aDd608C7F'],
59
83
  [Chains.SEP]: ['0xeE567Fe1712Faf6149d80dA1E6934E354124CfE3'],
@@ -62,6 +86,43 @@ export const uniV2Routers = {
62
86
  '0x636f6407B90661b73b1C0F7e24F4C79f624d0738',
63
87
  ],
64
88
  };
89
+ /**
90
+ * The swap venues the package ships with: PulseX V1 then V2 on PulseChain.
91
+ * Frozen. A caller who wants other routers passes its own
92
+ * {@link SwapVenues} (see `resolveSwapVenues`); this table is never mutated.
93
+ *
94
+ * Each factory is the router's own `router.factory()` read on chain — see
95
+ * {@link uniV2Factories}'s doc. The fee is 29 basis points for both
96
+ * deployments (measured, same doc).
97
+ */
98
+ export const defaultSwapVenues = Object.freeze({
99
+ [Number(Chains.PLS)]: Object.freeze([
100
+ Object.freeze({
101
+ kind: 'uniswap-v2',
102
+ chainId: Number(Chains.PLS),
103
+ router: '0x98bf93ebf5c380C0e6Ae8e192A7e2AE08edAcc02',
104
+ factory: '0x1715a3E4A142d8b698131108995174F37aEBA10D',
105
+ feeBasisPoints: 29,
106
+ label: 'PulseX V1',
107
+ }),
108
+ Object.freeze({
109
+ kind: 'uniswap-v2',
110
+ chainId: Number(Chains.PLS),
111
+ router: '0x165C3410fC91EF562C50559f7d2289fEbed552d9',
112
+ factory: '0x29eA7545DEf87022BAdc76323F373EA1e707C523',
113
+ feeBasisPoints: 29,
114
+ label: 'PulseX V2',
115
+ }),
116
+ ]),
117
+ });
118
+ /** One chain's routers: its default venues' routers, else the router-only entries. */
119
+ const defaultRoutersFor = (chain) => defaultSwapVenues[Number(chain)]?.map((venue) => venue.router) ?? routersWithoutVenue[chain] ?? [];
120
+ /**
121
+ * A map of chains to uni v2 router addresses. Frozen. PulseChain's entries
122
+ * derive from {@link defaultSwapVenues}, so the two cannot drift. Kept for
123
+ * compatibility; to swap on other routers pass `swapVenues` instead.
124
+ */
125
+ export const uniV2Routers = Object.freeze(Object.fromEntries(Object.values(Chains).map((chain) => [chain, Object.freeze([...defaultRoutersFor(chain)])])));
65
126
  /**
66
127
  * Each {@link uniV2Routers} entry's OWN factory address, same index, same
67
128
  * chain — `router.factory()` read live from `one.valve.city` on 2026-09-24.
@@ -86,16 +147,10 @@ export const uniV2Routers = {
86
147
  * salt collision) and worth this note so a future reader does not assume a
87
148
  * transcription error and "fix" it back to something wrong.
88
149
  */
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
- };
150
+ export const uniV2Factories = Object.freeze(Object.fromEntries(Object.values(Chains).map((chain) => [
151
+ chain,
152
+ Object.freeze((defaultSwapVenues[Number(chain)] ?? []).map((venue) => venue.factory)),
153
+ ])));
99
154
  /** A map of chains to native token symbols */
100
155
  export const nativeTokenSymbol = {
101
156
  [Chains.PLS]: 'PLS',
@@ -335,12 +390,23 @@ export const inferBridgeKey = ({ currentKey, provider, fromChain, toChain, isPro
335
390
  * @param isProd - whether this is a production build; testnets are off when true
336
391
  * @returns the group keyed by destination chain, or undefined when unknown
337
392
  */
338
- export const pathwayGroup = (provider, chain, isProd) => _.get(pathways, [provider, chain]) ||
339
- (!isProd ? _.get(testnetPathways, [provider, chain]) : undefined);
393
+ export const pathwayGroup = (provider, chain, isProd) => pathways[provider]?.[chain] || (!isProd ? testnetPathways[provider]?.[chain] : undefined);
394
+ /**
395
+ * Reads one pathway out of a provider, chain and chain map.
396
+ *
397
+ * Every level is optional at runtime: the testnet map leaves whole providers
398
+ * out, and a caller can hold a bridge key built from untrusted input.
399
+ *
400
+ * @param config - the pathway map to read
401
+ * @param bridgeKey - the provider, origin chain and destination chain
402
+ * @returns the pathway, or undefined when any level is missing
403
+ */
404
+ const lookupPathway = (config, [provider, from, to]) => config[provider]?.[from]?.[to];
340
405
  export const pathway = (bridgeKey, isProd, assetInAddress) => {
341
406
  if (!bridgeKey)
342
407
  return;
343
- let pathway = _.get(pathways, bridgeKey) || (!isProd ? _.get(testnetPathways, bridgeKey) : undefined);
408
+ let pathway = lookupPathway(pathways, bridgeKey) ||
409
+ (!isProd ? lookupPathway(testnetPathways, bridgeKey) : undefined);
344
410
  if (assetInAddress) {
345
411
  const addr = getAddress(assetInAddress);
346
412
  if (pathway?.settingOverrides?.[addr]) {
@@ -362,7 +428,7 @@ export const defaultAssetIn = ($bridgeKey, isProd) => {
362
428
  if (!$bridgeKey)
363
429
  return null;
364
430
  const conf = pathway($bridgeKey, isProd);
365
- const defaultAssetIn = _.get(conf, ['bridgedNativeAssetOut']);
431
+ const defaultAssetIn = conf?.bridgedNativeAssetOut;
366
432
  return defaultAssetIn;
367
433
  };
368
434
  /**
@@ -1,22 +1,26 @@
1
- import type { Hex } from 'viem';
1
+ import { type Hex } from 'viem';
2
2
  import type { DestinationCall } from './destination-calldata.js';
3
3
  import type { Ecosystem } from './ecosystems.js';
4
4
  import { type EvmDeposit, type OriginDeposit } from './origin-deposit.js';
5
5
  import type { ProviderId, ProviderQuoteContext } from './providers.js';
6
6
  import { type QuoteFee } from './quote-fees.js';
7
+ import type { ApprovalRequirement } from './settings.js';
7
8
  import type { RouteStep, Token } from './types.js';
8
9
  /**
9
- * The LI.FI `integrator` sent when a request leaves
10
- * {@link ConsolidatedQuoteRequest.lifiIntegrator} out.
10
+ * Gibs Finance's own LI.FI `integrator` label.
11
11
  *
12
- * KEPT AS A DEFAULT BECAUSE IT COSTS THE CALLER NOTHING. LI.FI's `integrator`
13
- * is an optional label: it changes neither the quote nor the rate limit, and it
14
- * moves no money unless a `fee` rides with it. A fee is the one case where the
15
- * label decides who gets paid, so a request that charges a fee must name its
16
- * own integrator — see {@link lifiAttribution}.
12
+ * NOT A DEFAULT. A request that leaves
13
+ * {@link ConsolidatedQuoteRequest.lifiIntegrator} out sends no `integrator`
14
+ * at all. An integrator label is attribution: LI.FI records the traffic under
15
+ * it, and pays any `fee` to the account behind it. A wallet that builds on this
16
+ * package must not attribute its users' routes to Gibs Finance without
17
+ * choosing to. The Gibs interface passes this value explicitly.
17
18
  */
18
19
  export declare const lifiIntegrator = "gibs.finance";
19
- /** Referral fee charged by this integrator on LI.FI routes (0.001 = 0.1%). */
20
+ /**
21
+ * The referral fee Gibs Finance charges on its own LI.FI routes (0.001 = 0.1%).
22
+ * No builder applies it. A request carries a fee only when it sets `lifiFee`.
23
+ */
20
24
  export declare const lifiReferralFeePercent = 0.001;
21
25
  /**
22
26
  * LI.FI's HTTP origin when the interface's `PUBLIC_LIFI_API_URL` build flag is
@@ -235,11 +239,10 @@ export type ConsolidatedQuoteRequest = {
235
239
  */
236
240
  lifiFee?: number;
237
241
  /**
238
- * The LI.FI `integrator` label. Left out, {@link lifiIntegrator} is sent;
239
- * `null` omits the field; a string is sent as-is. REQUIRED (as a string)
242
+ * The LI.FI `integrator` label. Left out or `null`, the field is not sent; a
243
+ * string is sent as-is. REQUIRED (as a string)
240
244
  * whenever {@link lifiFee} is positive: LI.FI pays a fee to the account behind
241
- * the integrator label, so a fee under the default label would pay Gibs
242
- * Finance, not you.
245
+ * the integrator label, so a fee needs a label that is yours.
243
246
  */
244
247
  lifiIntegrator?: string | null;
245
248
  /**
@@ -298,7 +301,7 @@ export type LifiContractCallsRequestBody = {
298
301
  toToken: Hex;
299
302
  toAmount: string;
300
303
  toFallbackAddress: Hex;
301
- /** Omitted when the request set `lifiIntegrator: null`. */
304
+ /** Present only when the request names a `lifiIntegrator`. */
302
305
  integrator?: string;
303
306
  /** Referral fee as a decimal fraction (e.g. 0.001 = 0.1%). Omitted when not charging a fee. */
304
307
  fee?: number;
@@ -313,7 +316,7 @@ export type LifiContractCallsRequestBody = {
313
316
  * @param request - the consolidated request's attribution fields
314
317
  * @returns the fields to merge into the request; empty when none apply
315
318
  * @throws when a positive `lifiFee` arrives without an explicit `lifiIntegrator`
316
- * string — that fee would otherwise be paid to the default integrator
319
+ * string — LI.FI would have nobody of yours to pay it to
317
320
  */
318
321
  export declare const lifiAttribution: (request: Pick<ConsolidatedQuoteRequest, "lifiFee" | "lifiIntegrator">) => {
319
322
  integrator?: string;
@@ -427,6 +430,97 @@ export type ConsolidatedQuote = {
427
430
  * path must never silently proceed on a Solana or Bitcoin payload.
428
431
  */
429
432
  export declare const evmDepositOf: (quote: ConsolidatedQuote) => EvmDeposit;
433
+ /** Why an aggregator's origin deposit is refused before anything is approved or sent. */
434
+ export type AggregatorOriginRefusal = {
435
+ reason: 'not-evm-deposit';
436
+ depositFamily: string;
437
+ } | {
438
+ reason: 'chain-mismatch';
439
+ depositChainId: number;
440
+ requestChainId: number;
441
+ } | {
442
+ reason: 'unverified-provider';
443
+ provider: string;
444
+ } | {
445
+ reason: 'unverified-chain';
446
+ provider: string;
447
+ chainId: number;
448
+ } | {
449
+ reason: 'spender-not-allowed';
450
+ provider: string;
451
+ spender: Hex;
452
+ } | {
453
+ reason: 'deposit-target-not-allowed';
454
+ provider: string;
455
+ target: Hex;
456
+ } | {
457
+ reason: 'deposit-shape';
458
+ provider: string;
459
+ detail: string;
460
+ } | {
461
+ reason: 'amount-mismatch';
462
+ provider: string;
463
+ /** Which figure disagreed: the quote's own, the native value, or the amount inside the calldata. */
464
+ field: 'quote-from-amount' | 'deposit-value' | 'calldata-amount';
465
+ expected: bigint;
466
+ actual: bigint;
467
+ } | {
468
+ reason: 'recipient-mismatch';
469
+ provider: string;
470
+ /** Which address disagreed: the native payee, the transfer payee, or the token a deposit names. */
471
+ field: 'deposit-to' | 'transfer-to' | 'calldata-token';
472
+ expected: string;
473
+ actual: string;
474
+ } | {
475
+ reason: 'lifi-guard';
476
+ detail: string;
477
+ };
478
+ /**
479
+ * What an aggregator's Ethereum origin deposit asks the wallet to send: the
480
+ * approval it needs first, if any, and the deposit itself. Both are checked
481
+ * before they are returned.
482
+ */
483
+ export type AggregatorOriginCalls = {
484
+ kind: 'calls';
485
+ approval: ApprovalRequirement | null;
486
+ deposit: EvmDeposit;
487
+ } | {
488
+ kind: 'refused';
489
+ refusal: AggregatorOriginRefusal;
490
+ };
491
+ /**
492
+ * Reads the approval and the deposit off an aggregator quote with an Ethereum
493
+ * origin, after checking both against what this code knows about the
494
+ * provider. The interface's aggregator press (`stores/consolidated-execute.ts`)
495
+ * and the SDK's execution planner both read them here, so neither can sign a
496
+ * call the other would refuse.
497
+ *
498
+ * WHAT IS CHECKED, BEFORE ANYTHING IS APPROVED OR SENT:
499
+ * - Every provider: when the request names the amount to send
500
+ * (`request.fromAmount`), the quote's own `fromAmount` must equal it.
501
+ * - LI.FI: `verifyLifiEvmExecution`: the Diamond for the chain, a known
502
+ * facet call, calldata that matches the request, and the decoded amount
503
+ * pulled from the reader equal to the amount to send.
504
+ * - Relay: the deposit target and the spender are Relay's depository for the
505
+ * chain (`relayDepositoryByChainId`). A native deposit carries the amount
506
+ * as `value` through `depositNative`; a token deposit carries no value and
507
+ * is `depositErc20` for the request's token and the amount.
508
+ * - NEAR Intents: no spender, and a plain payment of the amount to send to the
509
+ * quote's own deposit address (`quote.quoteId`), native or `transfer`.
510
+ * - Any other provider is refused. Its spender is unknown.
511
+ *
512
+ * The approval is for exactly the amount to send (the request's, else the
513
+ * quote's when the route is solved backwards and the request names none), on
514
+ * the request's origin chain. The native coin needs none.
515
+ *
516
+ * @param options.quote - the live quote to sign
517
+ * @param options.request - the request it answered
518
+ * @returns the checked approval and deposit, or why they are refused
519
+ */
520
+ export declare const aggregatorOriginCalls: ({ quote, request, }: {
521
+ quote: ConsolidatedQuote;
522
+ request: ConsolidatedQuoteRequest;
523
+ }) => AggregatorOriginCalls;
430
524
  /**
431
525
  * Normalizes a quote response from the contract-calls endpoint.
432
526
  *