Skip to content

Fix/align lend amount types#347

Open
thinktanktom wants to merge 3 commits into
ethereum-optimism:mainfrom
thinktanktom:fix/align-lend-amount-types
Open

Fix/align lend amount types#347
thinktanktom wants to merge 3 commits into
ethereum-optimism:mainfrom
thinktanktom:fix/align-lend-amount-types

Conversation

@thinktanktom
Copy link
Copy Markdown

Summary

Aligns the lend module's amount and position types with the pattern established by the swap module in #284. The core principle: developers pass human-readable numbers in, and receive human-readable numbers out with the same field names. Raw bigint values are always suffixed with Raw.

Closes #303


Problem

The lend module had an inconsistent type pattern where the same field name changed type between input and output:

// Input
amount: number         // human-readable (e.g. 100)

// Output — same name, completely different type
amount: bigint         // raw on-chain value (e.g. 100000000n)
balanceFormatted: string  // awkward Formatted suffix

This was a footgun for developers consuming the SDK: passing amount: 100 in and receiving amount: 100000000n back from the same field.


Changes

SDK types (packages/sdk/src/types/lend/base.ts)

Interface Before After
LendTransaction amount: bigint amount: number + amountRaw: bigint
LendMarketPosition balance: bigint balance: number + balanceRaw: bigint
LendMarketPosition balanceFormatted: string Removed (replaced by balance: number)
LendMarketPosition shares: bigint shares: number + sharesRaw: bigint
LendMarketPosition sharesFormatted: string Removed (replaced by shares: number)
LendClosePositionParams amount: bigint amountRaw: bigint (consistency with LendOpenPositionInternalParams)

SDK providers

  • LendProvider.ts: closePosition passes amountRaw to _closePosition
  • MorphoLendProvider: _openPosition, _closePosition, _getPosition updated to return new field shape using formatAssetAmount
  • AaveLendProvider: _openETHPosition, _openERC20Position, _closeETHPosition, _closeERC20Position, _getPosition updated
  • MockLendProvider: All mock helpers updated to produce correct amount/amountRaw/balanceRaw/sharesRaw fields

Demo backend

  • packages/demo/backend/src/types/lend.ts — no change needed; serializeBigInt handles the new *Raw bigint fields automatically

Demo frontend

  • packages/demo/frontend/src/types/api.tsPositionResponse updated
  • packages/demo/frontend/src/api/actionsApi.tsgetPosition deserializes balanceRaw/sharesRaw from string, passes balance/shares through as numbers
  • packages/demo/frontend/src/hooks/useWalletBalance.tsdepositedAmount derived from position.balance (number) instead of position.balanceFormatted (string)
  • packages/demo/frontend/src/hooks/useLendProvider.ts — position balance comparison updated

Tests

  • All assertions updated across LendProvider.test.ts, WalletLendNamespace.spec.ts, AaveLendProvider.test.ts, MorphoLendProvider.test.ts, useActivityLogging.spec.ts
  • All 375 SDK unit tests passing, all frontend tests passing

Before / After

// BEFORE
const position = await wallet.lend.getPosition({ marketId })
console.log(position.balance)         // 100000000n  ← bigint, confusing
console.log(position.balanceFormatted) // "100.00"    ← string, extra field

const tx = await wallet.lend.openPosition({ amount: 100, ... })
console.log(tx.amount) // 100000000n  ← bigint, doesn't match what you passed in

// AFTER
const position = await wallet.lend.getPosition({ marketId })
console.log(position.balance)    // 100      ← number, matches input type
console.log(position.balanceRaw) // 100000000n ← raw value, clearly named

const tx = await wallet.lend.openPosition({ amount: 100, ... })
console.log(tx.amount)    // 100        ← number, matches what you passed in
console.log(tx.amountRaw) // 100000000n ← raw value, clearly named

Notes

  • No changes to the public openPosition/closePosition call signatures — amount: number input is unchanged
  • formatAssetAmount from packages/sdk/src/utils/assets.ts is used for all bigint → number conversions (already existed in the codebase)
  • This is a breaking change for any consumer currently reading amount, balance, shares, balanceFormatted, or sharesFormatted off lend types — a changeset should be added before merge

Renames all references to "hosted" wallet provider to "embedded"
throughout the SDK to better align with industry terminology used
by providers like Privy, Dynamic, and Turnkey.

Changes:
- Rename wallet/*/providers/hosted/ → wallet/*/providers/embedded/
- Rename wallet/*/wallets/hosted/ → wallet/*/wallets/embedded/
- Rename HostedWalletProvider → EmbeddedWalletProvider
- Rename HostedWalletConfig → EmbeddedWalletConfig
- Rename EmbeddedProviderDeps, EmbeddedProviderFactory, etc.
- Rename hostedWalletConfig → embeddedWalletConfig in WalletConfig
- Rename hostedWalletProvider → embeddedWalletProvider in WalletNamespace
- Rename all *HostedWalletProvider* files to *EmbeddedWalletProvider*
- Add @deprecated aliases for HostedWalletConfig and hostedWalletConfig
- Add @deprecated getter for hostedWalletProvider in WalletNamespace

Closes ethereum-optimism#330
- LendTransaction: amount bigint → number + amountRaw bigint
- LendMarketPosition: balance/shares bigint → number + *Raw bigint
- Remove balanceFormatted/sharesFormatted (replaced by number fields)
- LendClosePositionParams: amount → amountRaw for consistency
- Update Morpho + Aave providers, mocks, and all consumers

Closes ethereum-optimism#303
@thinktanktom thinktanktom requested a review from a team as a code owner March 30, 2026 06:10
@thinktanktom thinktanktom requested a review from tremarkley March 30, 2026 06:10
@netlify
Copy link
Copy Markdown

netlify Bot commented Mar 30, 2026

👷 Deploy request for actions-ui pending review.

Visit the deploys page to approve it

Name Link
🔨 Latest commit 98d2926

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.

Align lend amount types with swap pattern

1 participant