Dual Interaction Layers

Two paths, one codebase
Every transaction component in the frontend branches on the isSafe prop. Safe mode uses gasless relay via Gelato; EOA mode sends transactions directly.

NMT supports two distinct ways for users to interact with DeFi protocols. Understanding which path a transaction takes is critical for working on any transaction-related code.

Deposit with wallet approval A deposit into Yearn on Base. The NMT modal (left) prepares the transaction; the wallet extension (right) shows the token approval for the user to sign.

The Two Modes

MODE 1: Delegate + Safe                    MODE 2: EOA (Direct Wallet)
========================                    ===========================

User's Wallet (EOA)                         User's Wallet (EOA)
       |                                           |
       | signs EIP-712 message                     | signs transaction directly
       v                                           v
DelegateBundler                             Blockchain (direct call)
       |
       | validates permissions
       v
Protocol Module (e.g. AaveModule)
       |
       | executes via Safe
       v
Gnosis Safe (holds funds)
       |
       v
Blockchain

Mode 1: Delegate + Safe

The user's funds live in a Gnosis Safe (smart wallet). A delegate executes DeFi strategies on their behalf, within the bounds of granted permissions.

Aspect Detail
Who holds the funds Gnosis Safe contract
Who signs The delegate (operator) signs an EIP-712 message
How it executes DelegateBundler validates signature and permissions, then routes calls through protocol modules
Who pays gas Gelato Relay (sponsored/gasless for the user)
Batching Multiple operations bundled into one atomic transaction
Native ETH Must be wrapped to WETH first — Safes can't use native ETH in swaps

Use case: Asset managers controlling client wallets. Advisors executing strategies for advisees. Institutional delegation.

Mode 2: EOA (Direct Wallet)

The user trades directly from their own wallet. No Safe, no delegation, no permission checks.

Aspect Detail
Who holds the funds The user's wallet (EOA)
Who signs The user signs the transaction directly
How it executes walletClient.sendTransaction() straight to the protocol contract
Who pays gas The user pays
Batching Each operation is a separate transaction
Native ETH Can be used directly

Use case: Personal trading. Users who want direct control without delegation overhead.

How the Code Branches

Throughout the frontend, the isSafe prop controls which execution path is taken. Every transaction component accepts it:

// Pattern used across all protocol components
export const AaveBalancesTable = ({
  address,
  isSafe = false,  // defaults to EOA mode
}: {
  address: string | null;
  isSafe?: boolean;
}) => {
  // ...

  const withdrawSelected = async () => {
    if (isSafe) {
      await withdrawFromSafe(positions, amounts);  // Bundler path
    } else {
      await withdrawEOA(position, amount);          // Direct path
    }
  };
};

Components that branch on isSafe:

Component Location
AaveBalancesTable features/transact/aave/aave-balances-table.tsx
UniswapV3PositionsTable features/transact/uniswap-v3/uniswap-v3-positions.tsx
UniswapV2PositionsTable features/transact/uniswap-v2/uniswap-v2-positions.tsx
YearnVaultPositionsTable features/transact/yearn/yearn-positions.tsx
MorphoPositionsTable features/transact/morpho/morpho-positions.tsx
AerodromePositions features/transact/aerodrome/aerodrome-positions.tsx
KrystalVaultPositionsTable features/transact/krystal/krystal-positions.tsx

Safe Path: Step by Step

When isSafe = true, a withdrawal from Aave looks like this:

1. PREPARE    — Build call array (approve + withdraw calls)
                via buildAaveWithdrawCall()

2. SIGN       — Delegate signs EIP-712 typed data:
                { callsDataHash, nonce, deadline }

3. SIMULATE   — DelegateBundler.simulateExecuteAndRevert()
                to catch errors before spending gas

4. RELAY      — Submit to Gelato Relay for sponsored execution
                (platform pays gas, not the user)

5. CONFIRM    — Poll Gelato for task status until confirmed

Key files:

  • Bundler service: features/delegations/services/bundler/service.ts
  • Relay service: features/delegations/services/relay-swap-service.ts

EOA Path: Step by Step

When isSafe = false, the same withdrawal looks like this:

1. PREPARE    — Encode the withdraw transaction calldata

2. SIGN+SEND  — walletClient.sendTransaction({
                  to: aavePoolAddress,
                  data: withdrawCalldata
                })

3. CONFIRM    — publicClient.waitForTransactionReceipt()

Key file: v2/transactions/swaps/hooks/use-execute-swap.ts

Token Swaps: Mode Differences

Token swaps have additional complexity because different swap providers have different Safe compatibility:

Swap Provider Safe Mode EOA Mode Notes
Relay (cross-chain) Yes Yes Safe wraps native ETH to WETH automatically
Relay (same-chain) Yes Yes Same WETH wrapping behavior
Cow Protocol Yes No Requires PRESIGN signing scheme (Safe-only)
Direct swap No Yes Standard sendTransaction

Why Cow Protocol is Safe-Only

Cow Protocol uses a PRESIGN signing scheme — the order is pre-signed on-chain through the Safe module rather than signed off-chain by an EOA. This enables MEV protection but requires the Safe infrastructure:

// Cow Swap always uses PRESIGN for Safe execution
const advancedSettings = {
  quoteRequest: {
    signingScheme: SigningScheme.PRESIGN,
    receiver: safeAddress,
  },
};

The Cow Swap module builds calls that go through the DelegateBundler:

  • buildCowSwapApprovalCall() — approve token spending
  • buildCowSwapSignOrderCall() — pre-sign the order on-chain

Decision Matrix

Scenario Mode Why
Advisor manages client portfolio Delegate + Safe Client retains custody, advisor operates within permissions
User wants gasless transactions Delegate + Safe Gelato Relay sponsors gas
User wants MEV-protected swaps Delegate + Safe Cow Protocol requires PRESIGN via Safe
User wants multi-step atomic operations Delegate + Safe DelegateBundler batches calls
User trades from personal wallet EOA Simpler, no Safe setup needed
User wants to use native ETH directly EOA Safes require WETH wrapping
Quick one-off swap EOA Less overhead than Safe setup

results matching ""

    No results matching ""