I'm assuming you refer to the official Uniswap V3 example here : https://docs.uniswap.org/sdk/guides/liquidity/adding and that your pool is initialized
Short answer: Uniswap handles the (un)wrapping.
Complete answer :
The main idea in adding liquidity is similar to how swaps are performed in V3:
- start from a periphery (optional) "helper" (NonfungiblePositionManager.sol here), which is inheriting LiquidityManagement.sol (from periphery/base). This is where you can find the (internal) addLiquidity function which, after computing the amount (price for start and end tick and Struct packing) will...
- ...call the low-level-ish mint function on the pool itself. This function is quite short, and can be summarized as: take note of the current pool balances - call the callback - take note and comparing the new pool balances.
The actual token transfers are done in the callback, which must be implemented by the contract calling pool.mint (here, LiquidityManagement does it for you). The callback uses pay() (from base/peripheryPayment), where you can easily see the (un)wrapping mechanism (pay is used by the swap callback too).
if (token == WETH9 && address(this).balance >= value) {
// pay with WETH9
IWETH9(WETH9).deposit{value: value}(); // wrap only what is needed to pay
IWETH9(WETH9).transfer(recipient, value);
Control schema:
Periphery Core
addLiquidity ---> pool.mint
mintCallback&Pay <---
---> pool.mint