@fenine/universal-router-sdk 1.0.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 (163) hide show
  1. package/README.md +331 -0
  2. package/dist/cjs/src/entities/Command.d.ts +12 -0
  3. package/dist/cjs/src/entities/Command.js +9 -0
  4. package/dist/cjs/src/entities/Command.js.map +1 -0
  5. package/dist/cjs/src/entities/actions/across.d.ts +21 -0
  6. package/dist/cjs/src/entities/actions/across.js +7 -0
  7. package/dist/cjs/src/entities/actions/across.js.map +1 -0
  8. package/dist/cjs/src/entities/actions/index.d.ts +3 -0
  9. package/dist/cjs/src/entities/actions/index.js +7 -0
  10. package/dist/cjs/src/entities/actions/index.js.map +1 -0
  11. package/dist/cjs/src/entities/actions/uniswap.d.ts +38 -0
  12. package/dist/cjs/src/entities/actions/uniswap.js +545 -0
  13. package/dist/cjs/src/entities/actions/uniswap.js.map +1 -0
  14. package/dist/cjs/src/entities/actions/unwrapWETH.d.ts +12 -0
  15. package/dist/cjs/src/entities/actions/unwrapWETH.js +33 -0
  16. package/dist/cjs/src/entities/actions/unwrapWETH.js.map +1 -0
  17. package/dist/cjs/src/entities/index.d.ts +2 -0
  18. package/dist/cjs/src/entities/index.js +6 -0
  19. package/dist/cjs/src/entities/index.js.map +1 -0
  20. package/dist/cjs/src/index.d.ts +14 -0
  21. package/dist/cjs/src/index.js +36 -0
  22. package/dist/cjs/src/index.js.map +1 -0
  23. package/dist/cjs/src/swapRouter.d.ts +103 -0
  24. package/dist/cjs/src/swapRouter.js +338 -0
  25. package/dist/cjs/src/swapRouter.js.map +1 -0
  26. package/dist/cjs/src/types/encodeSwaps.d.ts +149 -0
  27. package/dist/cjs/src/types/encodeSwaps.js +3 -0
  28. package/dist/cjs/src/types/encodeSwaps.js.map +1 -0
  29. package/dist/cjs/src/utils/commandParser.d.ts +34 -0
  30. package/dist/cjs/src/utils/commandParser.js +145 -0
  31. package/dist/cjs/src/utils/commandParser.js.map +1 -0
  32. package/dist/cjs/src/utils/computeEncodeSwapsAmounts.d.ts +8 -0
  33. package/dist/cjs/src/utils/computeEncodeSwapsAmounts.js +47 -0
  34. package/dist/cjs/src/utils/computeEncodeSwapsAmounts.js.map +1 -0
  35. package/dist/cjs/src/utils/constants.d.ts +39 -0
  36. package/dist/cjs/src/utils/constants.js +560 -0
  37. package/dist/cjs/src/utils/constants.js.map +1 -0
  38. package/dist/cjs/src/utils/eip712.d.ts +17 -0
  39. package/dist/cjs/src/utils/eip712.js +43 -0
  40. package/dist/cjs/src/utils/eip712.js.map +1 -0
  41. package/dist/cjs/src/utils/encodeSwapStep.d.ts +4 -0
  42. package/dist/cjs/src/utils/encodeSwapStep.js +61 -0
  43. package/dist/cjs/src/utils/encodeSwapStep.js.map +1 -0
  44. package/dist/cjs/src/utils/encodeV4Action.d.ts +8 -0
  45. package/dist/cjs/src/utils/encodeV4Action.js +97 -0
  46. package/dist/cjs/src/utils/encodeV4Action.js.map +1 -0
  47. package/dist/cjs/src/utils/getCurrencyAddress.d.ts +2 -0
  48. package/dist/cjs/src/utils/getCurrencyAddress.js +9 -0
  49. package/dist/cjs/src/utils/getCurrencyAddress.js.map +1 -0
  50. package/dist/cjs/src/utils/inputTokens.d.ts +23 -0
  51. package/dist/cjs/src/utils/inputTokens.js +58 -0
  52. package/dist/cjs/src/utils/inputTokens.js.map +1 -0
  53. package/dist/cjs/src/utils/normalizeEncodeSwapsSpec.d.ts +2 -0
  54. package/dist/cjs/src/utils/normalizeEncodeSwapsSpec.js +18 -0
  55. package/dist/cjs/src/utils/normalizeEncodeSwapsSpec.js.map +1 -0
  56. package/dist/cjs/src/utils/numbers.d.ts +7 -0
  57. package/dist/cjs/src/utils/numbers.js +27 -0
  58. package/dist/cjs/src/utils/numbers.js.map +1 -0
  59. package/dist/cjs/src/utils/pathCurrency.d.ts +3 -0
  60. package/dist/cjs/src/utils/pathCurrency.js +27 -0
  61. package/dist/cjs/src/utils/pathCurrency.js.map +1 -0
  62. package/dist/cjs/src/utils/routerCommands.d.ts +77 -0
  63. package/dist/cjs/src/utils/routerCommands.js +334 -0
  64. package/dist/cjs/src/utils/routerCommands.js.map +1 -0
  65. package/dist/cjs/src/utils/routerTradeAdapter.d.ts +73 -0
  66. package/dist/cjs/src/utils/routerTradeAdapter.js +139 -0
  67. package/dist/cjs/src/utils/routerTradeAdapter.js.map +1 -0
  68. package/dist/cjs/src/utils/validateEncodeSwaps.d.ts +2 -0
  69. package/dist/cjs/src/utils/validateEncodeSwaps.js +135 -0
  70. package/dist/cjs/src/utils/validateEncodeSwaps.js.map +1 -0
  71. package/dist/esm/src/entities/Command.d.ts +12 -0
  72. package/dist/esm/src/entities/Command.js +6 -0
  73. package/dist/esm/src/entities/Command.js.map +1 -0
  74. package/dist/esm/src/entities/actions/across.d.ts +21 -0
  75. package/dist/esm/src/entities/actions/across.js +3 -0
  76. package/dist/esm/src/entities/actions/across.js.map +1 -0
  77. package/dist/esm/src/entities/actions/index.d.ts +3 -0
  78. package/dist/esm/src/entities/actions/index.js +4 -0
  79. package/dist/esm/src/entities/actions/index.js.map +1 -0
  80. package/dist/esm/src/entities/actions/uniswap.d.ts +38 -0
  81. package/dist/esm/src/entities/actions/uniswap.js +541 -0
  82. package/dist/esm/src/entities/actions/uniswap.js.map +1 -0
  83. package/dist/esm/src/entities/actions/unwrapWETH.d.ts +12 -0
  84. package/dist/esm/src/entities/actions/unwrapWETH.js +28 -0
  85. package/dist/esm/src/entities/actions/unwrapWETH.js.map +1 -0
  86. package/dist/esm/src/entities/index.d.ts +2 -0
  87. package/dist/esm/src/entities/index.js +3 -0
  88. package/dist/esm/src/entities/index.js.map +1 -0
  89. package/dist/esm/src/index.d.ts +14 -0
  90. package/dist/esm/src/index.js +11 -0
  91. package/dist/esm/src/index.js.map +1 -0
  92. package/dist/esm/src/swapRouter.d.ts +103 -0
  93. package/dist/esm/src/swapRouter.js +333 -0
  94. package/dist/esm/src/swapRouter.js.map +1 -0
  95. package/dist/esm/src/types/encodeSwaps.d.ts +149 -0
  96. package/dist/esm/src/types/encodeSwaps.js +2 -0
  97. package/dist/esm/src/types/encodeSwaps.js.map +1 -0
  98. package/dist/esm/src/utils/commandParser.d.ts +34 -0
  99. package/dist/esm/src/utils/commandParser.js +137 -0
  100. package/dist/esm/src/utils/commandParser.js.map +1 -0
  101. package/dist/esm/src/utils/computeEncodeSwapsAmounts.d.ts +8 -0
  102. package/dist/esm/src/utils/computeEncodeSwapsAmounts.js +43 -0
  103. package/dist/esm/src/utils/computeEncodeSwapsAmounts.js.map +1 -0
  104. package/dist/esm/src/utils/constants.d.ts +39 -0
  105. package/dist/esm/src/utils/constants.js +552 -0
  106. package/dist/esm/src/utils/constants.js.map +1 -0
  107. package/dist/esm/src/utils/eip712.d.ts +17 -0
  108. package/dist/esm/src/utils/eip712.js +38 -0
  109. package/dist/esm/src/utils/eip712.js.map +1 -0
  110. package/dist/esm/src/utils/encodeSwapStep.d.ts +4 -0
  111. package/dist/esm/src/utils/encodeSwapStep.js +57 -0
  112. package/dist/esm/src/utils/encodeSwapStep.js.map +1 -0
  113. package/dist/esm/src/utils/encodeV4Action.d.ts +8 -0
  114. package/dist/esm/src/utils/encodeV4Action.js +92 -0
  115. package/dist/esm/src/utils/encodeV4Action.js.map +1 -0
  116. package/dist/esm/src/utils/getCurrencyAddress.d.ts +2 -0
  117. package/dist/esm/src/utils/getCurrencyAddress.js +5 -0
  118. package/dist/esm/src/utils/getCurrencyAddress.js.map +1 -0
  119. package/dist/esm/src/utils/inputTokens.d.ts +23 -0
  120. package/dist/esm/src/utils/inputTokens.js +51 -0
  121. package/dist/esm/src/utils/inputTokens.js.map +1 -0
  122. package/dist/esm/src/utils/normalizeEncodeSwapsSpec.d.ts +2 -0
  123. package/dist/esm/src/utils/normalizeEncodeSwapsSpec.js +14 -0
  124. package/dist/esm/src/utils/normalizeEncodeSwapsSpec.js.map +1 -0
  125. package/dist/esm/src/utils/numbers.d.ts +7 -0
  126. package/dist/esm/src/utils/numbers.js +19 -0
  127. package/dist/esm/src/utils/numbers.js.map +1 -0
  128. package/dist/esm/src/utils/pathCurrency.d.ts +3 -0
  129. package/dist/esm/src/utils/pathCurrency.js +23 -0
  130. package/dist/esm/src/utils/pathCurrency.js.map +1 -0
  131. package/dist/esm/src/utils/routerCommands.d.ts +77 -0
  132. package/dist/esm/src/utils/routerCommands.js +329 -0
  133. package/dist/esm/src/utils/routerCommands.js.map +1 -0
  134. package/dist/esm/src/utils/routerTradeAdapter.d.ts +73 -0
  135. package/dist/esm/src/utils/routerTradeAdapter.js +134 -0
  136. package/dist/esm/src/utils/routerTradeAdapter.js.map +1 -0
  137. package/dist/esm/src/utils/validateEncodeSwaps.d.ts +2 -0
  138. package/dist/esm/src/utils/validateEncodeSwaps.js +130 -0
  139. package/dist/esm/src/utils/validateEncodeSwaps.js.map +1 -0
  140. package/dist/types/src/entities/Command.d.ts +12 -0
  141. package/dist/types/src/entities/actions/across.d.ts +21 -0
  142. package/dist/types/src/entities/actions/index.d.ts +3 -0
  143. package/dist/types/src/entities/actions/uniswap.d.ts +38 -0
  144. package/dist/types/src/entities/actions/unwrapWETH.d.ts +12 -0
  145. package/dist/types/src/entities/index.d.ts +2 -0
  146. package/dist/types/src/index.d.ts +14 -0
  147. package/dist/types/src/swapRouter.d.ts +103 -0
  148. package/dist/types/src/types/encodeSwaps.d.ts +149 -0
  149. package/dist/types/src/utils/commandParser.d.ts +34 -0
  150. package/dist/types/src/utils/computeEncodeSwapsAmounts.d.ts +8 -0
  151. package/dist/types/src/utils/constants.d.ts +39 -0
  152. package/dist/types/src/utils/eip712.d.ts +17 -0
  153. package/dist/types/src/utils/encodeSwapStep.d.ts +4 -0
  154. package/dist/types/src/utils/encodeV4Action.d.ts +8 -0
  155. package/dist/types/src/utils/getCurrencyAddress.d.ts +2 -0
  156. package/dist/types/src/utils/inputTokens.d.ts +23 -0
  157. package/dist/types/src/utils/normalizeEncodeSwapsSpec.d.ts +2 -0
  158. package/dist/types/src/utils/numbers.d.ts +7 -0
  159. package/dist/types/src/utils/pathCurrency.d.ts +3 -0
  160. package/dist/types/src/utils/routerCommands.d.ts +77 -0
  161. package/dist/types/src/utils/routerTradeAdapter.d.ts +73 -0
  162. package/dist/types/src/utils/validateEncodeSwaps.d.ts +2 -0
  163. package/package.json +78 -0
package/README.md ADDED
@@ -0,0 +1,331 @@
1
+ # universal-router-sdk
2
+
3
+ This SDK facilitates interactions with the contracts in [Universal Router](https://github.com/Uniswap/universal-router)
4
+
5
+ ## Usage
6
+
7
+ Install latest version of universal-router-sdk. Then import the corresponding Trade class and Data object for each protocol you'd like to interact with.
8
+
9
+ ### Trading on Uniswap
10
+
11
+ warning: `swapERC20CallParameters()` to be deprecated in favor of `swapCallParameters()`
12
+
13
+ ```typescript
14
+ import { TradeType } from '@uniswap/sdk-core'
15
+ import { Trade as V2TradeSDK } from '@uniswap/v2-sdk'
16
+ import { Trade as V3TradeSDK } from '@uniswap/v3-sdk'
17
+ import { MixedRouteTrade, MixedRouteSDK, Trade as RouterTrade } from '@uniswap/router-sdk'
18
+
19
+ const options = { slippageTolerance, recipient }
20
+ const routerTrade = new RouterTrade({ v2Routes, v3Routes, mixedRoutes, tradeType: TradeType.EXACT_INPUT })
21
+ // Use the raw calldata and value returned to call into Universal Swap Router contracts
22
+ const { calldata, value } = SwapRouter.swapCallParameters(routerTrade, options)
23
+ ```
24
+
25
+ This SDK has two entry points for encoding swap calldata:
26
+
27
+ - **`SwapRouter.swapCallParameters(trade, options)`** — builds calldata from a high-level `RouterTrade` (shown above). Best when your swap fits as one or more independent linear routes through pools.
28
+ - **`SwapRouter.encodeSwaps(spec, swapSteps)`** — takes Universal Router commands directly, with the SDK adding ingress, fee, and settlement calldata around them. Best for topologies that don't fit a Trade, routing-service integrations, or advanced V4 compositions. See [Encoding Router-Provided Swap Steps](#encoding-router-provided-swap-steps-encodeswaps).
29
+
30
+ ## Running this package
31
+
32
+ Make sure you are running `node v18`
33
+ Install dependencies and run typescript unit tests
34
+
35
+ ```bash
36
+ yarn install
37
+ yarn test:hardhat
38
+ ```
39
+
40
+ Run forge integration tests
41
+
42
+ ```bash
43
+ forge install
44
+ yarn test:forge
45
+ ```
46
+
47
+ ## Encoding Router-Provided Swap Steps (`encodeSwaps`)
48
+
49
+ `SwapRouter.encodeSwaps(spec, swapSteps)` is an alternative entry point for callers that already produce explicit `SwapStep[]` plans (e.g. routing services) and want the SDK to wrap them in a safety envelope. It decouples route topology from SDK trade construction.
50
+
51
+ The router owns `swapSteps` (V2/V3/V4 swaps + any `WRAP_ETH` / `UNWRAP_WETH`). The SDK owns ingress, fees, final settlement, exact-output refund, and optional `safeMode`.
52
+
53
+ ### Swap Step Types
54
+
55
+ Each `SwapStep` is a 1:1 representation of a Universal Router command:
56
+
57
+ - `V2_SWAP_EXACT_IN` / `V2_SWAP_EXACT_OUT` — V2 swap (multi-hop via `path: address[]`)
58
+ - `V3_SWAP_EXACT_IN` / `V3_SWAP_EXACT_OUT` — V3 swap (multi-hop via packed `path: bytes`)
59
+ - `V4_SWAP` — wraps a sequence of V4 actions (`SWAP_EXACT_IN`, `SETTLE`, `TAKE`, etc.) for the V4 router module
60
+ - `WRAP_ETH` / `UNWRAP_WETH` — required when the route bridges native ETH and WETH
61
+
62
+ Routers compose these to express any supported route topology. The SDK does not infer wrap/unwrap commands — routers must include them when their route depends on it.
63
+
64
+ ### Basic Usage
65
+
66
+ ```typescript
67
+ import { SwapRouter, ROUTER_AS_RECIPIENT } from '@uniswap/universal-router-sdk'
68
+ import { CurrencyAmount, Percent, TradeType } from '@uniswap/sdk-core'
69
+
70
+ const { calldata, value } = SwapRouter.encodeSwaps(
71
+ {
72
+ tradeType: TradeType.EXACT_INPUT,
73
+ routing: {
74
+ inputToken: USDC,
75
+ outputToken: WETH,
76
+ amount: CurrencyAmount.fromRawAmount(USDC, '1000000000'),
77
+ quote: CurrencyAmount.fromRawAmount(WETH, '500000000000000000'),
78
+ },
79
+ slippageTolerance: new Percent(50, 10000), // 0.5%
80
+ recipient: '0x...',
81
+ },
82
+ [
83
+ {
84
+ type: 'V3_SWAP_EXACT_IN',
85
+ recipient: ROUTER_AS_RECIPIENT,
86
+ amountIn: '1000000000',
87
+ amountOutMin: '0', // SDK enforces final slippage via the trailing SWEEP
88
+ path: '0x...', // packed V3 path
89
+ },
90
+ ]
91
+ )
92
+ ```
93
+
94
+ ### What the SDK adds around `swapSteps`
95
+
96
+ 1. **Ingress**: `PERMIT2_TRANSFER_FROM` for ERC20 input, or `proxy.execute()` wrapping for `ApproveProxy`. Native input flows through `msg.value`.
97
+ 2. **Fee deduction** before settlement: portion (`PAY_PORTION` / `PAY_PORTION_FULL_PRECISION`) on exact-input, flat (`TRANSFER`) on exact-output.
98
+ 3. **Final SWEEP** of `outputToken` to recipient with the slippage-bounded floor.
99
+ 4. **Exact-output refund**: SWEEPs unused input back to recipient.
100
+ 5. **safeMode** (optional): trailing zero-min ETH SWEEP to recover dust or unintended `msg.value`.
101
+
102
+ ### Constraints
103
+
104
+ - All swap step recipients must be `ROUTER_AS_RECIPIENT` — the SDK's settlement sweeps need router custody to see the funds.
105
+ - `payerIsUser` is hardcoded to `false`; ingress runs once up-front via `PERMIT2_TRANSFER_FROM`.
106
+ - Routers must end with output in `routing.outputToken`. For exact-output, unused input must end in `routing.inputToken`.
107
+ - The final top-level `SWEEP` is appended by the SDK — don't include it in `swapSteps`.
108
+
109
+ ### Per-Hop Slippage
110
+
111
+ Per-hop bounds require Universal Router v2.1.1+ — set `urVersion: UniversalRouterVersion.V2_1_1` on `spec` to enable.
112
+
113
+ `encodeSwaps` accepts per-hop bounds as `minHopPriceX36` on each swap step, matching the contract parameter name. The value is a 1e36-scaled price floor.
114
+
115
+ ```typescript
116
+ {
117
+ type: 'V3_SWAP_EXACT_IN',
118
+ // ...
119
+ minHopPriceX36: ['995000000000000000000000000000000000', ...], // one per hop
120
+ }
121
+ ```
122
+
123
+ ## Signed Routes (Universal Router v2.1)
124
+
125
+ Universal Router v2.1 supports EIP712-signed route execution, enabling gasless transactions and intent-based trading.
126
+
127
+ **Important**: The SDK does not perform signing. It provides utilities to prepare EIP712 payloads and encode signed calldata. You sign with your own mechanism (wallet, KMS, hardware, etc.).
128
+
129
+ ### Basic Flow
130
+
131
+ ```typescript
132
+ import { SwapRouter, NONCE_SKIP_CHECK } from '@uniswap/universal-router-sdk'
133
+ import { Wallet } from '@ethersproject/wallet'
134
+
135
+ const wallet = new Wallet('0x...')
136
+ const chainId = 1
137
+ const routerAddress = '0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD'
138
+ const deadline = Math.floor(Date.now() / 1000) + 60 * 20
139
+
140
+ // 1. Generate regular swap calldata
141
+ const { calldata, value } = SwapRouter.swapCallParameters(trade, {
142
+ slippageTolerance: new Percent(50, 10000),
143
+ recipient: wallet.address,
144
+ deadline,
145
+ })
146
+
147
+ // 2. Get EIP712 payload to sign
148
+ const payload = SwapRouter.getExecuteSignedPayload(
149
+ calldata,
150
+ {
151
+ intent: '0x' + '0'.repeat(64), // Application-specific intent
152
+ data: '0x' + '0'.repeat(64), // Application-specific data
153
+ sender: wallet.address, // Or address(0) to skip sender verification
154
+ },
155
+ deadline,
156
+ chainId,
157
+ routerAddress
158
+ )
159
+
160
+ // 3. Sign externally (wallet/KMS/hardware)
161
+ const signature = await wallet._signTypedData(payload.domain, payload.types, payload.value)
162
+
163
+ // 4. Encode for executeSigned()
164
+ const { calldata: signedCalldata, value: signedValue } = SwapRouter.encodeExecuteSigned(
165
+ calldata,
166
+ signature,
167
+ {
168
+ intent: payload.value.intent,
169
+ data: payload.value.data,
170
+ sender: payload.value.sender,
171
+ nonce: payload.value.nonce, // Must match what was signed
172
+ },
173
+ deadline,
174
+ BigNumber.from(value)
175
+ )
176
+
177
+ // 5. Submit transaction
178
+ await wallet.sendTransaction({
179
+ to: routerAddress,
180
+ data: signedCalldata,
181
+ value: signedValue,
182
+ })
183
+ ```
184
+
185
+ ### Nonce Management
186
+
187
+ - **Random nonce (default)**: Omit `nonce` parameter - SDK generates random nonce
188
+ - **Skip nonce check**: Use `NONCE_SKIP_CHECK` sentinel to allow signature reuse
189
+ - **Custom nonce**: Provide your own nonce for ordering
190
+
191
+ ```typescript
192
+ import { NONCE_SKIP_CHECK } from '@uniswap/universal-router-sdk'
193
+
194
+ // Reusable signature (no nonce check)
195
+ const payload = SwapRouter.getExecuteSignedPayload(
196
+ calldata,
197
+ {
198
+ intent: '0x...',
199
+ data: '0x...',
200
+ sender: '0x0000000000000000000000000000000000000000', // Skip sender verification too
201
+ nonce: NONCE_SKIP_CHECK, // Allow signature reuse
202
+ },
203
+ deadline,
204
+ chainId,
205
+ routerAddress
206
+ )
207
+ ```
208
+
209
+ ### Sender Verification
210
+
211
+ - **Verify sender**: Pass the actual sender address (e.g., `wallet.address`)
212
+ - **Skip verification**: Pass `'0x0000000000000000000000000000000000000000'`
213
+
214
+ The SDK automatically sets `verifySender` based on whether sender is address(0).
215
+
216
+ ## Cross-Chain Bridging with Across (Universal Router v2.1)
217
+
218
+ Universal Router v2.1 integrates with Across Protocol V3 to enable seamless cross-chain bridging after swaps. This allows you to swap tokens on one chain and automatically bridge them to another chain in a single transaction.
219
+
220
+ ### Basic Usage
221
+
222
+ ```typescript
223
+ import { SwapRouter } from '@uniswap/universal-router-sdk'
224
+ import { BigNumber } from 'ethers'
225
+
226
+ // 1. Prepare your swap (e.g., USDC → WETH on mainnet)
227
+ const { calldata, value } = SwapRouter.swapCallParameters(trade, swapOptions, [
228
+ {
229
+ // Bridge configuration
230
+ depositor: userAddress,
231
+ recipient: userAddress, // Recipient on destination chain
232
+ inputToken: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', // WETH mainnet
233
+ outputToken: '0x4200000000000000000000000000000000000006', // WETH optimism
234
+ inputAmount: BigNumber.from('1000000000000000000'), // 1 WETH
235
+ outputAmount: BigNumber.from('990000000000000000'), // 0.99 WETH (with fees)
236
+ destinationChainId: 10, // Optimism
237
+ exclusiveRelayer: '0x0000000000000000000000000000000000000000',
238
+ quoteTimestamp: Math.floor(Date.now() / 1000),
239
+ fillDeadline: Math.floor(Date.now() / 1000) + 3600,
240
+ exclusivityDeadline: 0,
241
+ message: '0x',
242
+ useNative: false,
243
+ },
244
+ ])
245
+ ```
246
+
247
+ ### Swap + Bridge Example
248
+
249
+ ```typescript
250
+ // Swap USDC to WETH, then bridge WETH to Optimism
251
+ const bridgeParams = {
252
+ depositor: userAddress,
253
+ recipient: userAddress, // Can be different address on destination
254
+ inputToken: WETH_MAINNET,
255
+ outputToken: WETH_OPTIMISM,
256
+ inputAmount: CONTRACT_BALANCE, // Use entire swap output
257
+ outputAmount: expectedOutputAmount,
258
+ destinationChainId: 10,
259
+ exclusiveRelayer: '0x0000000000000000000000000000000000000000',
260
+ quoteTimestamp: Math.floor(Date.now() / 1000),
261
+ fillDeadline: Math.floor(Date.now() / 1000) + 3600,
262
+ exclusivityDeadline: 0,
263
+ message: '0x', // Optional message to execute on destination
264
+ useNative: false, // Set to true to bridge native ETH
265
+ }
266
+
267
+ const { calldata, value } = SwapRouter.swapCallParameters(
268
+ trade,
269
+ swapOptions,
270
+ [bridgeParams] // Array of bridge operations
271
+ )
272
+ ```
273
+
274
+ ### Using CONTRACT_BALANCE
275
+
276
+ When bridging after a swap, you often don't know the exact output amount. Use `CONTRACT_BALANCE` to bridge the entire contract balance:
277
+
278
+ ```typescript
279
+ import { CONTRACT_BALANCE } from '@uniswap/universal-router-sdk'
280
+
281
+ const bridgeParams = {
282
+ // ... other params
283
+ inputAmount: CONTRACT_BALANCE, // Bridge entire balance after swap
284
+ // ... other params
285
+ }
286
+ ```
287
+
288
+ ### Multiple Bridge Operations
289
+
290
+ You can perform multiple bridge operations after a swap:
291
+
292
+ ```typescript
293
+ const { calldata, value } = SwapRouter.swapCallParameters(trade, swapOptions, [
294
+ {
295
+ // Bridge 50% to Optimism
296
+ inputToken: WETH_MAINNET,
297
+ outputToken: WETH_OPTIMISM,
298
+ inputAmount: BigNumber.from('500000000000000000'),
299
+ destinationChainId: 10,
300
+ // ... other params
301
+ },
302
+ {
303
+ // Bridge remaining USDC to Arbitrum
304
+ inputToken: USDC_MAINNET,
305
+ outputToken: USDC_ARBITRUM,
306
+ inputAmount: CONTRACT_BALANCE,
307
+ destinationChainId: 42161,
308
+ // ... other params
309
+ },
310
+ ])
311
+ ```
312
+
313
+ ### Native ETH Bridging
314
+
315
+ To bridge native ETH instead of WETH:
316
+
317
+ ```typescript
318
+ const bridgeParams = {
319
+ inputToken: WETH_ADDRESS, // Must be WETH address
320
+ outputToken: WETH_ON_DESTINATION,
321
+ useNative: true, // Bridge as native ETH
322
+ // ... other params
323
+ }
324
+ ```
325
+
326
+ ### Important Notes
327
+
328
+ 1. **Across Quote**: Bridge parameters (especially `outputAmount`, `quoteTimestamp`, `fillDeadline`) should come from the Across API quote
329
+ 2. **Recipient Address**: Can be different from the sender, allowing cross-chain transfers to other addresses
330
+ 3. **Message Passing**: The `message` field allows executing arbitrary calls on the destination chain
331
+ 4. **Slippage**: The `outputAmount` already accounts for bridge fees and slippage
@@ -0,0 +1,12 @@
1
+ import { RoutePlanner } from '../utils/routerCommands';
2
+ export type TradeConfig = {
3
+ allowRevert: boolean;
4
+ };
5
+ export declare enum RouterActionType {
6
+ UniswapTrade = "UniswapTrade",
7
+ UnwrapWETH = "UnwrapWETH"
8
+ }
9
+ export interface Command {
10
+ tradeType: RouterActionType;
11
+ encode(planner: RoutePlanner, config: TradeConfig): void;
12
+ }
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RouterActionType = void 0;
4
+ var RouterActionType;
5
+ (function (RouterActionType) {
6
+ RouterActionType["UniswapTrade"] = "UniswapTrade";
7
+ RouterActionType["UnwrapWETH"] = "UnwrapWETH";
8
+ })(RouterActionType = exports.RouterActionType || (exports.RouterActionType = {}));
9
+ //# sourceMappingURL=Command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Command.js","sourceRoot":"","sources":["../../../../src/entities/Command.ts"],"names":[],"mappings":";;;AAMA,IAAY,gBAGX;AAHD,WAAY,gBAAgB;IAC1B,iDAA6B,CAAA;IAC7B,6CAAyB,CAAA;AAC3B,CAAC,EAHW,gBAAgB,GAAhB,wBAAgB,KAAhB,wBAAgB,QAG3B"}
@@ -0,0 +1,21 @@
1
+ import { BigNumberish } from 'ethers';
2
+ /**
3
+ * Parameters for Across V4 Deposit V3 command
4
+ * Used for cross-chain bridging via Across Protocol V3 SpokePool
5
+ */
6
+ export type AcrossV4DepositV3Params = {
7
+ depositor: string;
8
+ recipient: string;
9
+ inputToken: string;
10
+ outputToken: string;
11
+ inputAmount: BigNumberish;
12
+ outputAmount: BigNumberish;
13
+ destinationChainId: number;
14
+ exclusiveRelayer: string;
15
+ quoteTimestamp: number;
16
+ fillDeadline: number;
17
+ exclusivityDeadline: number;
18
+ message: string;
19
+ useNative: boolean;
20
+ };
21
+ export { CONTRACT_BALANCE } from '../../utils/constants';
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CONTRACT_BALANCE = void 0;
4
+ // Export CONTRACT_BALANCE constant for convenience
5
+ var constants_1 = require("../../utils/constants");
6
+ Object.defineProperty(exports, "CONTRACT_BALANCE", { enumerable: true, get: function () { return constants_1.CONTRACT_BALANCE; } });
7
+ //# sourceMappingURL=across.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"across.js","sourceRoot":"","sources":["../../../../../src/entities/actions/across.ts"],"names":[],"mappings":";;;AAsBA,mDAAmD;AACnD,mDAAwD;AAA/C,6GAAA,gBAAgB,OAAA"}
@@ -0,0 +1,3 @@
1
+ export * from './uniswap';
2
+ export * from './unwrapWETH';
3
+ export * from './across';
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./uniswap"), exports);
5
+ tslib_1.__exportStar(require("./unwrapWETH"), exports);
6
+ tslib_1.__exportStar(require("./across"), exports);
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/entities/actions/index.ts"],"names":[],"mappings":";;;AAAA,oDAAyB;AACzB,uDAA4B;AAC5B,mDAAwB"}
@@ -0,0 +1,38 @@
1
+ import { RoutePlanner } from '../../utils/routerCommands';
2
+ import { Trade as RouterTrade, SwapOptions as RouterSwapOptions } from '@uniswap/router-sdk';
3
+ import { Permit2Permit } from '../../utils/inputTokens';
4
+ import { Currency, TradeType } from '@fenine/sdk-core';
5
+ import { Command, RouterActionType, TradeConfig } from '../Command';
6
+ import { UniversalRouterVersion } from '../../utils/constants';
7
+ import { BigNumberish } from 'ethers';
8
+ export type FlatFeeOptions = {
9
+ amount: BigNumberish;
10
+ recipient: string;
11
+ };
12
+ export declare enum TokenTransferMode {
13
+ Permit2 = "Permit2",
14
+ ApproveProxy = "ApproveProxy"
15
+ }
16
+ export type SwapOptions = Omit<RouterSwapOptions, 'inputTokenPermit'> & {
17
+ useRouterBalance?: boolean;
18
+ inputTokenPermit?: Permit2Permit;
19
+ flatFee?: FlatFeeOptions;
20
+ safeMode?: boolean;
21
+ urVersion?: UniversalRouterVersion;
22
+ tokenTransferMode?: TokenTransferMode;
23
+ chainId?: number;
24
+ };
25
+ export declare class UniswapTrade implements Command {
26
+ trade: RouterTrade<Currency, Currency, TradeType>;
27
+ options: SwapOptions;
28
+ readonly tradeType: RouterActionType;
29
+ readonly payerIsUser: boolean;
30
+ constructor(trade: RouterTrade<Currency, Currency, TradeType>, options: SwapOptions);
31
+ get isAllV4(): boolean;
32
+ get inputRequiresWrap(): boolean;
33
+ get inputRequiresUnwrap(): boolean;
34
+ get outputRequiresWrap(): boolean;
35
+ get outputRequiresUnwrap(): boolean;
36
+ get outputRequiresTransition(): boolean;
37
+ encode(planner: RoutePlanner, _config: TradeConfig): void;
38
+ }