Skip to content

feat(nextjs-defi-lending-moonwell): Moonwell USDC lending recipe (Base) - #73

Open
bprofiro wants to merge 1 commit into
dynamic-labs-oss:mainfrom
moonwell-fi:feat/nextjs-defi-lending-moonwell
Open

feat(nextjs-defi-lending-moonwell): Moonwell USDC lending recipe (Base)#73
bprofiro wants to merge 1 commit into
dynamic-labs-oss:mainfrom
moonwell-fi:feat/nextjs-defi-lending-moonwell

Conversation

@bprofiro

@bprofiro bprofiro commented Aug 18, 2026

Copy link
Copy Markdown

What this adds

examples/nextjs-defi-lending-moonwell — supply and withdraw USDC on Moonwell (Base) with a Dynamic embedded wallet. Structured after nextjs-defi-lending-morpho: JS SDK + react hooks, raw viem + minimal hand-rolled ABIs, headless email-OTP sign-in, WaaS bootstrap on userChanged via getChainsMissingWaasWalletAccounts().

  • Market list + live APYs from api.moonwell.fi/v1/markets, deprecated markets filtered out. Markets are keyed by mToken address: native USDC and the legacy USDbC market both report the mUSDC symbol.
  • Supply is approve → mint; withdraw is redeemUnderlying, or redeem of the full mToken balance when the user picks Max, so no dust is stranded by an exchange-rate tick.
  • Balances derive from exchangeRateStored (mTokenBalance * rate / 1e18) — the mToken balance never changes; the rate carries the interest.
  • Compound v2 return-code guard: Moonwell's markets answer some failures with a non-zero return code instead of reverting, so every write simulates first and asserts the code is 0.

Demo

a.mov

Implementation notes reviewers may care about

Each of these bit us during real-wallet testing and is documented inline:

  • The networksData transformer pins Base as the embedded wallet's default network — a fresh wallet otherwise opens on the first EVM network in the environment.
  • simulateContract is passed walletClient.account (the account object). An address string parses into a json-rpc account, and writeContract prefers the request's account — the transaction then goes to the RPC as eth_sendTransaction, which fails.
  • A supply chained straight onto an approval retries the simulate on stale-allowance reverts; the receipt proving the approval mined doesn't guarantee the next read sees the new allowance.

Recipe doc

RECIPE.mdx in the example directory is the companion doc for your recipes directory, mirroring the Morpho recipe's structure. Every code block is a verbatim excerpt of this example. Happy to move or reformat it to wherever your Mintlify source lives.

Running it

cd examples/nextjs-defi-lending-moonwell
cp .env.example .env.local   # set NEXT_PUBLIC_DYNAMIC_ENV_ID
pnpm install && pnpm dev

Dashboard prerequisites: Base under Chains & Networks, Embedded Wallets, Email sign-in, and http://localhost:3000 in Allowed Origins. Reads and broadcasts default to Moonwell's public Base RPC (rpc.moonwell.fi), since mainnet.base.org rate-limits browser traffic.

Tested end-to-end on Base mainnet with real funds: approve, mint, partial redeemUnderlying, and full redeem.

Supply and withdraw USDC on Moonwell (Base) with a Dynamic embedded
wallet, structured after nextjs-defi-lending-morpho: JS SDK + react
hooks, raw viem + minimal ABIs, headless email OTP, WaaS bootstrap via
getChainsMissingWaasWalletAccounts().

Market list and live APYs come from api.moonwell.fi/v1/markets with
deprecated markets filtered out; markets are keyed by mToken address
because native USDC and legacy USDbC both report the mUSDC symbol.
Supplying is approve -> mint; withdrawals use redeemUnderlying, or
redeem of the full mToken balance for Max so no dust is stranded.
Balances derive from exchangeRateStored. Every write simulates first
and asserts the Compound v2 return code is zero, since these markets
answer some failures with a code instead of a revert.

RECIPE.mdx is the companion recipe doc for the docs site, mirroring the
Morpho recipe's structure; every code block is a verbatim excerpt of
this example.
@vercel

vercel Bot commented Aug 18, 2026

Copy link
Copy Markdown

@bprofiro is attempting to deploy a commit to the Dynamic-xyz Team on Vercel.

A member of the Team first needs to authorize it.

@vercel

vercel Bot commented Aug 18, 2026

Copy link
Copy Markdown

Deployment failed for project dynamic-morpho with the following error:

There is no GitHub account connected to this Vercel account.

@vercel

vercel Bot commented Aug 18, 2026

Copy link
Copy Markdown

Deployment failed for project lifi with the following error:

There is no GitHub account connected to this Vercel account.

@vercel

vercel Bot commented Aug 18, 2026

Copy link
Copy Markdown

Deployment failed for project dynamic-gasless-starter with the following error:

There is no GitHub account connected to this Vercel account.

@vercel

vercel Bot commented Aug 18, 2026

Copy link
Copy Markdown

Deployment failed for project dynamic-aave with the following error:

There is no GitHub account connected to this Vercel account.

@vercel

vercel Bot commented Aug 18, 2026

Copy link
Copy Markdown

Deployment failed for project sidebar-example with the following error:

There is no GitHub account connected to this Vercel account.

@vercel

vercel Bot commented Aug 18, 2026

Copy link
Copy Markdown

Deployment failed for project circle-gateway with the following error:

There is no GitHub account connected to this Vercel account.

@vercel

vercel Bot commented Aug 18, 2026

Copy link
Copy Markdown

Deployment failed for project blindpay with the following error:

There is no GitHub account connected to this Vercel account.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant