0
# Utilities & Extensions
1
2
Extended multicall and payment utilities for transaction batching and native ETH handling. These utilities provide enhanced functionality beyond standard Uniswap SDK utilities, including advanced validation and fee handling.
3
4
## Capabilities
5
6
### MulticallExtended Class
7
8
Enhanced multicall functionality with deadline and previous block hash validation support.
9
10
```typescript { .api }
11
/**
12
* Abstract class providing extended multicall functionality with validation
13
*/
14
abstract class MulticallExtended {
15
/** Contract interface for IMulticallExtended */
16
static INTERFACE: Interface;
17
18
/**
19
* Encode multicall with optional validation (deadline or previous block hash)
20
* @param calldatas - Single calldata string or array of calldata strings
21
* @param validation - Optional deadline (number) or previous block hash (0x-prefixed string)
22
* @returns Encoded multicall function data
23
*/
24
static encodeMulticall(calldatas: string | string[], validation?: Validation): string;
25
}
26
```
27
28
### PaymentsExtended Class
29
30
Extended payment utilities with fee support for token sweeping and ETH wrapping/unwrapping.
31
32
```typescript { .api }
33
/**
34
* Abstract class providing extended payment functionality with fee support
35
*/
36
abstract class PaymentsExtended {
37
/** Contract interface for IPeripheryPaymentsWithFeeExtended */
38
static INTERFACE: Interface;
39
40
/**
41
* Encode WETH9 unwrapping with optional fee
42
* @param amountMinimum - Minimum amount to unwrap
43
* @param recipient - Optional recipient address (uses msg.sender if not provided)
44
* @param feeOptions - Optional fee configuration
45
* @returns Encoded function data for WETH unwrap
46
*/
47
static encodeUnwrapWETH9(amountMinimum: JSBI, recipient?: string, feeOptions?: FeeOptions): string;
48
49
/**
50
* Encode token sweeping with optional fee
51
* @param token - Token to sweep
52
* @param amountMinimum - Minimum amount to sweep
53
* @param recipient - Optional recipient address (uses msg.sender if not provided)
54
* @param feeOptions - Optional fee configuration
55
* @returns Encoded function data for token sweep
56
*/
57
static encodeSweepToken(
58
token: Token,
59
amountMinimum: JSBI,
60
recipient?: string,
61
feeOptions?: FeeOptions
62
): string;
63
64
/**
65
* Encode token pull (transfer from user to contract)
66
* @param token - Token to pull
67
* @param amount - Amount to pull
68
* @returns Encoded function data for token pull
69
*/
70
static encodePull(token: Token, amount: JSBI): string;
71
72
/**
73
* Encode ETH wrapping to WETH
74
* @param amount - Amount of ETH to wrap
75
* @returns Encoded function data for ETH wrap
76
*/
77
static encodeWrapETH(amount: JSBI): string;
78
}
79
```
80
81
### Validation Types
82
83
Type definitions for validation parameters used in extended multicall.
84
85
```typescript { .api }
86
/**
87
* Validation parameter - either deadline (timestamp) or previous block hash
88
*/
89
type Validation = BigintIsh | string;
90
91
/**
92
* Validate and parse a bytes32 string (for block hash validation)
93
* @param bytes32 - Hex string to validate (must be 64 hex characters with 0x prefix)
94
* @returns Lowercase hex string
95
* @throws Error if format is invalid
96
*/
97
function validateAndParseBytes32(bytes32: string): string;
98
```
99
100
### Fee Encoding Utilities
101
102
Internal utility functions for encoding fees in basis points.
103
104
```typescript { .api }
105
/**
106
* Encode fee percentage as basis points
107
* @param fee - Fee as Percent object
108
* @returns Hex-encoded fee in basis points (fee * 10000)
109
*/
110
function encodeFeeBips(fee: Percent): string;
111
```
112
113
### Path and Route Utilities
114
115
Utilities for working with mixed routes and currency paths.
116
117
```typescript { .api }
118
/**
119
* Utility function to return consecutive sections of Pools or Pairs in a MixedRoute partitioned by protocol
120
* @param route - Mixed route to partition
121
* @returns Nested array of pools grouped by protocol type
122
*/
123
function partitionMixedRouteByProtocol(route: MixedRouteSDK<Currency, Currency>): TPool[][];
124
125
/**
126
* Get the output token of an array of pools given the first input token
127
* @param pools - Array of pools to traverse
128
* @param firstInputToken - Starting input token
129
* @returns Final output token after traversing all pools
130
*/
131
function getOutputOfPools(pools: TPool[], firstInputToken: Currency): Currency;
132
133
/**
134
* Get the appropriate path currency for a given currency and pool
135
* @param currency - Currency to find path representation for
136
* @param pool - Pool to check currency against
137
* @returns Currency as it should appear in the path (may be wrapped version)
138
*/
139
function getPathCurrency(currency: Currency, pool: TPool): Currency;
140
141
/**
142
* Create currency amount with the appropriate path currency
143
* @param amount - Original currency amount
144
* @param pool - Pool to get path currency for
145
* @returns Currency amount with path-appropriate currency
146
*/
147
function amountWithPathCurrency(amount: CurrencyAmount<Currency>, pool: TPool): CurrencyAmount<Currency>;
148
```
149
150
### Mixed Route Path Encoding
151
152
Utilities for encoding mixed routes into hex paths for on-chain execution.
153
154
```typescript { .api }
155
/**
156
* Converts a mixed route to a hex encoded path for exactIn swaps
157
* @param route - Mixed route to encode
158
* @param useMixedRouterQuoteV2 - Whether to use Mixed Quoter V2 encoding for v4 pools
159
* @returns Hex-encoded path string
160
*/
161
function encodeMixedRouteToPath(
162
route: MixedRouteSDK<Currency, Currency>,
163
useMixedRouterQuoteV2?: boolean
164
): string;
165
```
166
167
**Usage Examples:**
168
169
```typescript
170
import {
171
MulticallExtended,
172
PaymentsExtended,
173
validateAndParseBytes32,
174
partitionMixedRouteByProtocol
175
} from "@uniswap/router-sdk";
176
177
// Basic multicall without validation
178
const calldatas = [
179
"0x...", // First call
180
"0x...", // Second call
181
"0x..." // Third call
182
];
183
184
const basicMulticall = MulticallExtended.encodeMulticall(calldatas);
185
```
186
187
```typescript
188
// Multicall with deadline validation
189
const deadline = Math.floor(Date.now() / 1000) + 1800; // 30 minutes
190
const multicallWithDeadline = MulticallExtended.encodeMulticall(calldatas, deadline);
191
192
// Multicall with previous block hash validation
193
const previousBlockHash = "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef";
194
const validatedBlockHash = validateAndParseBytes32(previousBlockHash);
195
const multicallWithBlockHash = MulticallExtended.encodeMulticall(calldatas, validatedBlockHash);
196
```
197
198
```typescript
199
// ETH and token payment operations
200
import { Token, Percent } from "@uniswap/sdk-core";
201
import JSBI from "jsbi";
202
203
const token = new Token(1, "0x...", 18, "USDC", "USD Coin");
204
const amount = JSBI.BigInt("1000000000"); // 1000 tokens
205
206
// Unwrap WETH to ETH
207
const unwrapCalldata = PaymentsExtended.encodeUnwrapWETH9(amount);
208
209
// Unwrap WETH with fee
210
const feeOptions = {
211
fee: new Percent(30, 10000), // 0.3% fee
212
recipient: "0x742d35Cc6435C6329Eb54F0d86C05B1E11a02E6B"
213
};
214
const unwrapWithFeeCalldata = PaymentsExtended.encodeUnwrapWETH9(amount, undefined, feeOptions);
215
```
216
217
```typescript
218
// Token operations
219
const sweepCalldata = PaymentsExtended.encodeSweepToken(token, amount);
220
const pullCalldata = PaymentsExtended.encodePull(token, amount);
221
const wrapCalldata = PaymentsExtended.encodeWrapETH(amount);
222
223
// Sweep token with fee to specific recipient
224
const sweepWithFeeCalldata = PaymentsExtended.encodeSweepToken(
225
token,
226
amount,
227
"0x742d35Cc6435C6329Eb54F0d86C05B1E11a02E6B", // recipient
228
feeOptions
229
);
230
```
231
232
```typescript
233
// Mixed route utilities
234
import { MixedRouteSDK, encodeMixedRouteToPath } from "@uniswap/router-sdk";
235
236
const mixedRoute = new MixedRouteSDK([v2Pair, v3Pool], tokenA, tokenB);
237
238
// Partition route by protocol
239
const sections = partitionMixedRouteByProtocol(mixedRoute);
240
console.log(`Route has ${sections.length} protocol sections`);
241
242
sections.forEach((section, index) => {
243
const protocolType = section[0].constructor.name;
244
console.log(`Section ${index}: ${section.length} ${protocolType} pools`);
245
});
246
247
// Get final output
248
const finalOutput = getOutputOfPools(mixedRoute.pools, tokenA);
249
console.log("Final output token:", finalOutput.symbol);
250
```
251
252
```typescript
253
// Path encoding for on-chain execution
254
const encodedPath = encodeMixedRouteToPath(mixedRoute);
255
console.log("Encoded path:", encodedPath);
256
257
// Use V2 quoter encoding
258
const v2EncodedPath = encodeMixedRouteToPath(mixedRoute, true);
259
console.log("V2 quoter encoded path:", v2EncodedPath);
260
```
261
262
```typescript
263
// Path currency utilities
264
import { getPathCurrency, amountWithPathCurrency } from "@uniswap/router-sdk";
265
266
const pathCurrency = getPathCurrency(ETH, pool); // Might return WETH for wrapped pools
267
const pathAmount = amountWithPathCurrency(ethAmount, pool);
268
269
console.log("Original currency:", ETH.symbol);
270
console.log("Path currency:", pathCurrency.symbol);
271
console.log("Path amount currency:", pathAmount.currency.symbol);
272
```
273
274
```typescript
275
// Complete transaction construction example
276
const transactionCalldatas = [
277
// Pull tokens from user
278
PaymentsExtended.encodePull(tokenIn, inputAmount),
279
280
// Execute swap
281
swapCalldata,
282
283
// Unwrap WETH to ETH if needed
284
PaymentsExtended.encodeUnwrapWETH9(outputAmount, recipient),
285
286
// Sweep any remaining tokens
287
PaymentsExtended.encodeSweepToken(tokenOut, JSBI.BigInt(0))
288
];
289
290
// Batch all operations with deadline
291
const finalCalldata = MulticallExtended.encodeMulticall(
292
transactionCalldatas,
293
Math.floor(Date.now() / 1000) + 1800
294
);
295
296
// Execute transaction
297
const transaction = {
298
to: ROUTER_ADDRESS,
299
data: finalCalldata,
300
value: inputIsETH ? inputAmount.toString() : "0"
301
};
302
```
303
304
### Error Handling
305
306
Common validation and error scenarios:
307
308
```typescript
309
// Validate block hash format
310
try {
311
const validated = validateAndParseBytes32("0x123"); // Too short
312
} catch (error) {
313
console.error("Invalid block hash format:", error.message);
314
}
315
316
// Check for valid path currencies
317
try {
318
const pathCurrency = getPathCurrency(currency, pool);
319
} catch (error) {
320
if (error.message.includes("Expected currency")) {
321
console.error("Currency not found in pool:", error.message);
322
}
323
}
324
325
// Validate pool compatibility in mixed routes
326
function validateMixedRoute(route: MixedRouteSDK<Currency, Currency>) {
327
try {
328
const sections = partitionMixedRouteByProtocol(route);
329
console.log(`Valid mixed route with ${sections.length} protocol sections`);
330
} catch (error) {
331
console.error("Invalid mixed route:", error.message);
332
}
333
}
334
```