Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
module.exports = {
// Stop config cascading at the repo root — without this, linting inside a
// nested checkout (e.g. a git worktree under .claude/worktrees/) merges the
// outer checkout's config and ESLint aborts on the twice-resolved prettier
// plugin.
root: true,
extends: [
'next/core-web-vitals',
'prettier',
Expand Down
5 changes: 5 additions & 0 deletions .github/actions/build/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ inputs:
description: enables cypress
required: false
default: 'true'
NEXT_PUBLIC_FUNKIT_API_KEY:
description: funkit checkout API key (publishable, client-side). Without it the funkit checkout host stays unmounted.
required: false
default: ''

runs:
using: 'composite'
Expand Down Expand Up @@ -89,3 +93,4 @@ runs:
NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID: '${{ inputs.NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID }}'
NEXT_PUBLIC_NARVAL_CLIENT_ID: '${{ inputs.NEXT_PUBLIC_NARVAL_CLIENT_ID }}'
NEXT_PUBLIC_IS_CYPRESS_ENABLED: '${{ inputs.NEXT_PUBLIC_IS_CYPRESS_ENABLED }}'
NEXT_PUBLIC_FUNKIT_API_KEY: '${{ inputs.NEXT_PUBLIC_FUNKIT_API_KEY }}'
1 change: 1 addition & 0 deletions .github/workflows/build-test-deploy-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ jobs:
NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID: ${{ secrets.WALLET_CONNECT_PROJECT_ID }}
NEXT_PUBLIC_NARVAL_CLIENT_ID: ${{ secrets.NEXT_PUBLIC_NARVAL_CLIENT_ID }}
NEXT_PUBLIC_IS_CYPRESS_ENABLED: ${{ matrix.build.cypress_enabled }}
NEXT_PUBLIC_FUNKIT_API_KEY: ${{ secrets.FUNKIT_API_KEY }}

- name: Upload artifacts
uses: ./.github/actions/upload-artifacts
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/build-test-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ jobs:
NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID: ${{ secrets.WALLET_CONNECT_PROJECT_ID }}
NEXT_PUBLIC_NARVAL_CLIENT_ID: ${{ secrets.NEXT_PUBLIC_NARVAL_CLIENT_ID }}
NEXT_PUBLIC_IS_CYPRESS_ENABLED: ${{ matrix.build.cypress_enabled }}
NEXT_PUBLIC_FUNKIT_API_KEY: ${{ secrets.FUNKIT_API_KEY }}

- name: Upload artifacts
uses: ./.github/actions/upload-artifacts
Expand All @@ -58,6 +59,7 @@ jobs:
uses: ./.github/actions/build
with:
NEXT_PUBLIC_ENV: 'staging'
NEXT_PUBLIC_FUNKIT_API_KEY: ${{ secrets.FUNKIT_API_KEY }}

- name: Upload artifacts
uses: ./.github/actions/upload-artifacts
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ yarn-debug.log*
yarn-error.log*

# local env files
.env
.env.local
.env.development.local
.env.test.local
Expand Down
8 changes: 7 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@
"protobufjs": "^7.5.5",
"qs": "^6.14.1",
"@types/react": "^18.3.30",
"@types/react-dom": "^18.3.7"
"@types/react-dom": "^18.3.7",
"bignumber.js": "^9.3.1",
"axios": "^1.18.0",
"tronweb/ethers/ws": "^8.21.0"
},
"scripts": {
"dev": "next dev",
Expand Down Expand Up @@ -50,6 +53,8 @@
"@emotion/react": "11.10.4",
"@emotion/server": "latest",
"@emotion/styled": "11.10.4",
"@funkit/chains": "^2.0.0",
"@funkit/connect": "^9.24.0",
"@heroicons/react": "^1.0.6",
"@lingui/core": "^4.14.0",
"@lingui/react": "^4.14.1",
Expand Down Expand Up @@ -99,6 +104,7 @@
"remark-gfm": "^3.0.1",
"sonner": "^2.0.3",
"tiny-invariant": "^1.3.1",
"tronweb": "^6.0.4",
"viem": "2.45.1",
"wagmi": "^2.15.2",
"zustand": "^5.0.2"
Expand Down
14 changes: 14 additions & 0 deletions pages/_app.page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import '/public/fonts/inter/inter.css';
import '/src/styles/variables.css';
// Preflight must come before funkit's own styles so funkit rules win source-order ties.
import '/src/ui-config/funkit/funkitPreflight.css';
import '@funkit/connect/styles.css';

import { AaveClient, AaveProvider } from '@aave/react';
import { CacheProvider, EmotionCache } from '@emotion/react';
Expand Down Expand Up @@ -51,6 +54,16 @@ const BridgeModal = dynamic(() =>
import('src/components/transactions/Bridge/BridgeModal').then((module) => module.BridgeModal)
);

// ssr: false (unlike the other modal hosts) because `@funkit/connect` is a
// client-only, ESM/browser package.
const FunkitCheckout = dynamic(
() =>
import('src/components/transactions/FunCheckout/FunkitCheckout').then(
(module) => module.FunkitCheckout
),
{ ssr: false }
);

const BorrowModal = dynamic(() =>
import('src/components/transactions/Borrow/BorrowModal').then((module) => module.BorrowModal)
);
Expand Down Expand Up @@ -164,6 +177,7 @@ export default function MyApp(props: MyAppProps) {
<GasStationProvider>
{getLayout(<Component {...pageProps} />)}
<SupplyModal />
<FunkitCheckout />
<WithdrawModal />
<BorrowModal />
<RepayModal />
Expand Down
88 changes: 88 additions & 0 deletions src/components/transactions/FunCheckout/FunSupplyButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { Trans } from '@lingui/macro';
import { Box, Button, ButtonProps } from '@mui/material';
import { ReactNode } from 'react';

import { useFunSupplyATokenIcon } from './useFunSupplyATokenIcon';
import { useSupplyButtonAction } from './useSupplyButtonAction';

export type FunSupplyButtonProps = Omit<ButtonProps, 'onClick' | 'children'> & {
/** Reserve underlying address (matched case-insensitively against the allowlist). */
underlyingAsset: string;
/** Reserve display name — forwarded to the native supply modal fallback. */
name: string;
/** Patched display symbol of the underlying (drives the funkit checkout title). */
symbol: string;
/**
* Symbol used to generate the ringed aToken icon. Often equals `symbol`, but
* can differ (e.g. wrapped tokens), so it's passed explicitly.
*/
iconSymbol: string;
/** Aave's `supplyAPY` — a 0–1 fraction. */
supplyAPY: string | number;
/** Collateral flag shown in the funkit checkout (`collateralizationEnabled`). */
collateralEnabled: boolean;
/** Analytics funnel for the native supply modal fallback. Defaults to `'dashboard'`. */
funnel?: string;
/** The native supply modal's reserve-page flag (`openSupply`'s 5th arg). Defaults to `false`. */
isReserve?: boolean;
/** Button label. Defaults to a translated "Supply". */
children?: ReactNode;
};

/**
* The Supply button, everywhere. It owns the funkit branch so individual call
* sites can't forget it: renders the hidden ringed-aToken icon generator and
* routes the click through `useSupplyButtonAction` (funkit checkout for the
* allowlisted Core-mainnet assets, native Aave supply modal otherwise). Every
* MUI `Button` prop (`sx`, `variant`, `disabled`, `fullWidth`, `data-cy`, …)
* passes straight through, so it drops into any layout.
*
* Adding a new Supply entry point? Render this instead of calling `openSupply`
* directly — keeping the funkit branch in one place is the whole point (ENG-4228).
*/
export function FunSupplyButton({
underlyingAsset,
name,
symbol,
iconSymbol,
supplyAPY,
collateralEnabled,
funnel,
isReserve,
children,
...buttonProps
}: FunSupplyButtonProps) {
const handleSupplyClick = useSupplyButtonAction({ funnel, isReserve });
const { aTokenBase64, generator } = useFunSupplyATokenIcon(underlyingAsset, iconSymbol);

return (
<>
{/* Hidden ringed-aToken icon generator (fun-routed rows only). Wrapped out
of flow so it never participates as a flex/grid item in the host layout
— it's a 0×0 element and would otherwise take a slot / introduce a gap. */}
{generator && (
<Box component="span" sx={{ position: 'absolute', width: 0, height: 0 }}>
{generator}
</Box>
)}
<Button
variant="contained"
{...buttonProps}
onClick={() =>
handleSupplyClick({
underlyingAsset,
name,
symbol,
aTokenBase64,
supplyAPY,
collateralEnabled,
})
}
>
{children ?? <Trans>Supply</Trans>}
</Button>
</>
);
}

export default FunSupplyButton;
Loading
Loading