> ## Documentation Index
> Fetch the complete documentation index at: https://unevenlabs-docs-drift-src-aa153b3060-2d3471a.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Wallet Detection

> How to detect wallet types and set the explicitDeposit parameter for optimal user experience

When using Protocol v2 on EVM chains, you need to detect whether your user's
wallet is an **EOA (Externally Owned Account)** or a **Smart Wallet** to
properly set the `explicitDeposit` parameter in your quote requests.

## Understanding Wallet Types

**EOAs (Externally Owned Accounts)** are regular wallets controlled by a private
key, like MetaMask, Coinbase Wallet, and hardware wallets. These wallets can
only execute one transaction at a time and cannot batch multiple operations
together.

**Smart Wallets** are contract-based wallets that can execute multiple
operations in a single transaction. Examples include Gnosis Safe, Argent, and
ERC-4337 compatible wallets. Smart wallets can batch approvals and deposits
atomically, making multi-step flows more user-friendly.

## The Problem

The EVM protocol deposit flow sends funds to Relay Depository contracts.
For ERC20 token deposits, there are two possible transaction flows:

**Explicit Deposits (2 transactions):**

1. User approves the Relay Depository contract to spend their tokens
2. User calls the `depositErc20` function to transfer tokens with an order ID

**Implicit Deposits (1 transaction):**

1. User transfers tokens to the Depository with the order ID encoded in
   transaction calldata

The challenge is that **implicit deposits only work reliably for EOAs**, while
**explicit deposits work for all wallet types but create poor UX for EOAs** who
must execute two separate transactions.

## The Solution

By detecting wallet type, you can set the `explicitDeposit` parameter to choose
the optimal flow:

* **`explicitDeposit: false`** - Enables implicit deposits for EOAs (1
  transaction)
* **`explicitDeposit: true`** - Uses explicit approval flow for smart wallets (2
  transactions, can be batched)
* **Default**: `true` (safe fallback for all wallet types)

## When to Use Wallet Detection

You should implement wallet detection when:

* Using `protocolVersion: "v2"` or `"preferV2"`
* User is on an EVM chain
* User is depositing ERC20 tokens (not native ETH)
* You want to optimize transaction flow for your users

For native ETH deposits, wallet detection is not necessary since no approval is
required.

## Detection Methods

### 1. Smart Wallet Capabilities (EIP-5792)

Check if the wallet advertises smart wallet capabilities:

```typescript theme={null}
const capabilities = await wallet.getCapabilities({
	account: wallet.account,
	chainId,
});

const hasSmartWalletCapabilities = Boolean(
	capabilities?.atomicBatch?.supported ||
		capabilities?.paymasterService?.supported ||
		capabilities?.auxiliaryFunds?.supported ||
		capabilities?.sessionKeys?.supported
);
```

### 2. Contract Code Detection

Check if the wallet address has deployed contract code:

```typescript theme={null}
const code = await publicClient.getCode({
	address: walletAddress,
});

const hasCode = Boolean(code && code !== "0x");
```

### 3. EIP-7702 Delegation Detection

Check if the wallet uses EIP-7702 delegation (code starts with `0xef01`):

```typescript theme={null}
const isEIP7702Delegated = Boolean(
	code && code.toLowerCase().startsWith("0xef01")
);
```

**Note**: EIP-7702 delegated accounts are technically EOAs but gain smart wallet
capabilities through authorization signatures. They require
`explicitDeposit: true` for reliable batching and execution.

### Final Determination

```typescript theme={null}
const isSmartWallet =
	hasSmartWalletCapabilities || hasCode || isEIP7702Delegated;
const isEOA = !isSmartWallet;

// Set explicitDeposit based on wallet type
const explicitDeposit = !isEOA || isEIP7702Delegated;
```

## Safety Checks

### Zero Native Balance Check

If the user has zero native currency (ETH, MATIC, etc.), force
`explicitDeposit: true` to avoid failed transactions due to insufficient gas:

```typescript theme={null}
if (nativeBalance === 0n) {
	explicitDeposit = true;
}
```

### Low Transaction Count Check

If the wallet has 1 or fewer transactions on the source chain, force
`explicitDeposit: true` as this may indicate a new wallet requiring explicit
handling:

```typescript theme={null}
if (transactionCount <= 1) {
	explicitDeposit = true;
}
```

## Implementation Example

Here's a complete implementation for detecting wallet types:

```typescript expandable theme={null}
export const detectWalletType = async (
	wallet: WalletClient,
	chainId: number
) => {
	if (!wallet.account) {
		return { isEOA: false, isEIP7702Delegated: false };
	}

	try {
		// Check 1: Smart wallet capabilities
		let hasSmartWalletCapabilities = false;
		try {
			const capabilities = await wallet.getCapabilities({
				account: wallet.account,
				chainId,
			});

			hasSmartWalletCapabilities = Boolean(
				capabilities?.atomicBatch?.supported ||
					capabilities?.paymasterService
						?.supported ||
					capabilities?.auxiliaryFunds
						?.supported ||
					capabilities?.sessionKeys?.supported
			);
		} catch (capabilitiesError) {
			// Wallet doesn't support capabilities API
		}

		// Check 2 & 3: Contract code detection
		const publicClient = createPublicClient({
			chain: getChainById(chainId),
			transport: http(),
		});

		const code = await publicClient.getCode({
			address: wallet.account.address,
		});

		const hasCode = Boolean(code && code !== "0x");
		const isEIP7702Delegated = Boolean(
			code && code.toLowerCase().startsWith("0xef01")
		);

		const isSmartWallet =
			hasSmartWalletCapabilities ||
			hasCode ||
			isEIP7702Delegated;
		const isEOA = !isSmartWallet;

		return { isEOA, isEIP7702Delegated };
	} catch (error) {
		// On error, assume not EOA (safer default)
		return { isEOA: false, isEIP7702Delegated: false };
	}
};
```

## Example Scenarios

| Wallet Type | Detection Result | explicitDeposit | User Experience |
| - | - | - | - |
| Regular EOA (MetaMask, Coinbase) | EOA detected | `false` | 1 transaction |
| Smart Wallet (Gnosis Safe, Argent) | Smart wallet detected | `true` | 2 transactions (can be batched) |
| EIP-7702 Delegated EOA | Smart wallet detected | `true` | 2 transactions (can be batched) |
| Detection Error | Unknown | `true` | 2 transactions (safe fallback) |

## API Usage

Include the `explicitDeposit` parameter in your quote requests:

```typescript theme={null}
const quoteRequest = {
	user: userAddress,
	originChainId: sourceChainId,
	destinationChainId: targetChainId,
	originCurrency: sourceCurrencyAddress,
	destinationCurrency: targetCurrencyAddress,
	recipient: recipientAddress,
	amount: amountInWei,
	tradeType: "EXACT_INPUT",
	protocolVersion: "preferV2",
	explicitDeposit: explicitDepositValue, // Based on your detection
};
```

## Expected User Experience

### For EOA Users (`explicitDeposit: false`)

```
✅ Step 1: Transfer USDC to the Depository with the order ID encoded in calldata
✅ One wallet confirmation
✅ Faster execution and lower cost
✅ Simpler, more intuitive user experience
```

### For Smart Wallet Users (`explicitDeposit: true`)

```
✅ Step 1: Approve Relay Depository contract to spend USDC
✅ Step 2: Call depositErc20() to deposit USDC
✅ Steps can be batched into single confirmation (ERC-4337/EIP-5792)
✅ Reliable, predictable execution through Depository architecture
✅ Full smart wallet capabilities (fee sponsorship, session keys, etc.)
```

## Best Practices

1. **Handle errors gracefully** - Return
   `{ isEOA: false, isEIP7702Delegated: false }` on errors (safer default)
2. **Add timeout** - Detection should timeout after \~1 second to avoid blocking
   UX
3. **Cache results** - Cache detection results per wallet/chain combination to
   avoid repeated calls
4. **Include safety checks** - Always check native balance and transaction count
   as additional safety measures
5. **Only use with Protocol v2** - The `explicitDeposit` parameter is only
   relevant for Protocol v2

## Troubleshooting

### Detection Returns Incorrect Results

* Ensure you're using the correct chain ID
* Verify the RPC endpoint is returning accurate data
* Check that wallet capabilities API is properly supported

### Quote Requests Failing

* Verify `explicitDeposit` is only included when using v2 protocol
* Ensure user has sufficient native currency for gas
* Check that the wallet address is valid

By implementing proper wallet detection, you can provide optimal user experience
for both EOA and smart wallet users while ensuring transaction reliability.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.