Skip to content

Commit 8cfc620

Browse files
authored
Merge branch 'main' into feat/add-monad
2 parents d6bee5a + bd23eb1 commit 8cfc620

26 files changed

Lines changed: 2353 additions & 74 deletions

.eslintrc.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
module.exports = {
2+
// Stop config cascading at the repo root — without this, linting inside a
3+
// nested checkout (e.g. a git worktree under .claude/worktrees/) merges the
4+
// outer checkout's config and ESLint aborts on the twice-resolved prettier
5+
// plugin.
6+
root: true,
27
extends: [
38
'next/core-web-vitals',
49
'prettier',

.github/actions/build/action.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ inputs:
4545
description: enables cypress
4646
required: false
4747
default: 'true'
48+
NEXT_PUBLIC_FUNKIT_API_KEY:
49+
description: funkit checkout API key (publishable, client-side). Without it the funkit checkout host stays unmounted.
50+
required: false
51+
default: ''
4852

4953
runs:
5054
using: 'composite'
@@ -89,3 +93,4 @@ runs:
8993
NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID: '${{ inputs.NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID }}'
9094
NEXT_PUBLIC_NARVAL_CLIENT_ID: '${{ inputs.NEXT_PUBLIC_NARVAL_CLIENT_ID }}'
9195
NEXT_PUBLIC_IS_CYPRESS_ENABLED: '${{ inputs.NEXT_PUBLIC_IS_CYPRESS_ENABLED }}'
96+
NEXT_PUBLIC_FUNKIT_API_KEY: '${{ inputs.NEXT_PUBLIC_FUNKIT_API_KEY }}'

.github/workflows/build-test-deploy-dev.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ jobs:
3939
NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID: ${{ secrets.WALLET_CONNECT_PROJECT_ID }}
4040
NEXT_PUBLIC_NARVAL_CLIENT_ID: ${{ secrets.NEXT_PUBLIC_NARVAL_CLIENT_ID }}
4141
NEXT_PUBLIC_IS_CYPRESS_ENABLED: ${{ matrix.build.cypress_enabled }}
42+
NEXT_PUBLIC_FUNKIT_API_KEY: ${{ secrets.FUNKIT_API_KEY }}
4243

4344
- name: Upload artifacts
4445
uses: ./.github/actions/upload-artifacts

.github/workflows/build-test-deploy.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ jobs:
3939
NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID: ${{ secrets.WALLET_CONNECT_PROJECT_ID }}
4040
NEXT_PUBLIC_NARVAL_CLIENT_ID: ${{ secrets.NEXT_PUBLIC_NARVAL_CLIENT_ID }}
4141
NEXT_PUBLIC_IS_CYPRESS_ENABLED: ${{ matrix.build.cypress_enabled }}
42+
NEXT_PUBLIC_FUNKIT_API_KEY: ${{ secrets.FUNKIT_API_KEY }}
4243

4344
- name: Upload artifacts
4445
uses: ./.github/actions/upload-artifacts
@@ -58,6 +59,7 @@ jobs:
5859
uses: ./.github/actions/build
5960
with:
6061
NEXT_PUBLIC_ENV: 'staging'
62+
NEXT_PUBLIC_FUNKIT_API_KEY: ${{ secrets.FUNKIT_API_KEY }}
6163

6264
- name: Upload artifacts
6365
uses: ./.github/actions/upload-artifacts

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ yarn-debug.log*
2727
yarn-error.log*
2828

2929
# local env files
30+
.env
3031
.env.local
3132
.env.development.local
3233
.env.test.local

package.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@
88
"protobufjs": "^7.5.5",
99
"qs": "^6.14.1",
1010
"@types/react": "^18.3.30",
11-
"@types/react-dom": "^18.3.7"
11+
"@types/react-dom": "^18.3.7",
12+
"bignumber.js": "^9.3.1",
13+
"axios": "^1.18.0",
14+
"tronweb/ethers/ws": "^8.21.0"
1215
},
1316
"scripts": {
1417
"dev": "next dev",
@@ -50,6 +53,8 @@
5053
"@emotion/react": "11.10.4",
5154
"@emotion/server": "latest",
5255
"@emotion/styled": "11.10.4",
56+
"@funkit/chains": "^2.0.0",
57+
"@funkit/connect": "^9.24.0",
5358
"@heroicons/react": "^1.0.6",
5459
"@lingui/core": "^4.14.0",
5560
"@lingui/react": "^4.14.1",
@@ -99,6 +104,7 @@
99104
"remark-gfm": "^3.0.1",
100105
"sonner": "^2.0.3",
101106
"tiny-invariant": "^1.3.1",
107+
"tronweb": "^6.0.4",
102108
"viem": "2.45.1",
103109
"wagmi": "^2.15.2",
104110
"zustand": "^5.0.2"

pages/_app.page.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import '/public/fonts/inter/inter.css';
22
import '/src/styles/variables.css';
3+
// Preflight must come before funkit's own styles so funkit rules win source-order ties.
4+
import '/src/ui-config/funkit/funkitPreflight.css';
5+
import '@funkit/connect/styles.css';
36

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

57+
// ssr: false (unlike the other modal hosts) because `@funkit/connect` is a
58+
// client-only, ESM/browser package.
59+
const FunkitCheckout = dynamic(
60+
() =>
61+
import('src/components/transactions/FunCheckout/FunkitCheckout').then(
62+
(module) => module.FunkitCheckout
63+
),
64+
{ ssr: false }
65+
);
66+
5467
const BorrowModal = dynamic(() =>
5568
import('src/components/transactions/Borrow/BorrowModal').then((module) => module.BorrowModal)
5669
);
@@ -164,6 +177,7 @@ export default function MyApp(props: MyAppProps) {
164177
<GasStationProvider>
165178
{getLayout(<Component {...pageProps} />)}
166179
<SupplyModal />
180+
<FunkitCheckout />
167181
<WithdrawModal />
168182
<BorrowModal />
169183
<RepayModal />
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import { Trans } from '@lingui/macro';
2+
import { Box, Button, ButtonProps } from '@mui/material';
3+
import { ReactNode } from 'react';
4+
5+
import { useFunSupplyATokenIcon } from './useFunSupplyATokenIcon';
6+
import { useSupplyButtonAction } from './useSupplyButtonAction';
7+
8+
export type FunSupplyButtonProps = Omit<ButtonProps, 'onClick' | 'children'> & {
9+
/** Reserve underlying address (matched case-insensitively against the allowlist). */
10+
underlyingAsset: string;
11+
/** Reserve display name — forwarded to the native supply modal fallback. */
12+
name: string;
13+
/** Patched display symbol of the underlying (drives the funkit checkout title). */
14+
symbol: string;
15+
/**
16+
* Symbol used to generate the ringed aToken icon. Often equals `symbol`, but
17+
* can differ (e.g. wrapped tokens), so it's passed explicitly.
18+
*/
19+
iconSymbol: string;
20+
/** Aave's `supplyAPY` — a 0–1 fraction. */
21+
supplyAPY: string | number;
22+
/** Collateral flag shown in the funkit checkout (`collateralizationEnabled`). */
23+
collateralEnabled: boolean;
24+
/** Analytics funnel for the native supply modal fallback. Defaults to `'dashboard'`. */
25+
funnel?: string;
26+
/** The native supply modal's reserve-page flag (`openSupply`'s 5th arg). Defaults to `false`. */
27+
isReserve?: boolean;
28+
/** Button label. Defaults to a translated "Supply". */
29+
children?: ReactNode;
30+
};
31+
32+
/**
33+
* The Supply button, everywhere. It owns the funkit branch so individual call
34+
* sites can't forget it: renders the hidden ringed-aToken icon generator and
35+
* routes the click through `useSupplyButtonAction` (funkit checkout for the
36+
* allowlisted Core-mainnet assets, native Aave supply modal otherwise). Every
37+
* MUI `Button` prop (`sx`, `variant`, `disabled`, `fullWidth`, `data-cy`, …)
38+
* passes straight through, so it drops into any layout.
39+
*
40+
* Adding a new Supply entry point? Render this instead of calling `openSupply`
41+
* directly — keeping the funkit branch in one place is the whole point (ENG-4228).
42+
*/
43+
export function FunSupplyButton({
44+
underlyingAsset,
45+
name,
46+
symbol,
47+
iconSymbol,
48+
supplyAPY,
49+
collateralEnabled,
50+
funnel,
51+
isReserve,
52+
children,
53+
...buttonProps
54+
}: FunSupplyButtonProps) {
55+
const handleSupplyClick = useSupplyButtonAction({ funnel, isReserve });
56+
const { aTokenBase64, generator } = useFunSupplyATokenIcon(underlyingAsset, iconSymbol);
57+
58+
return (
59+
<>
60+
{/* Hidden ringed-aToken icon generator (fun-routed rows only). Wrapped out
61+
of flow so it never participates as a flex/grid item in the host layout
62+
— it's a 0×0 element and would otherwise take a slot / introduce a gap. */}
63+
{generator && (
64+
<Box component="span" sx={{ position: 'absolute', width: 0, height: 0 }}>
65+
{generator}
66+
</Box>
67+
)}
68+
<Button
69+
variant="contained"
70+
{...buttonProps}
71+
onClick={() =>
72+
handleSupplyClick({
73+
underlyingAsset,
74+
name,
75+
symbol,
76+
aTokenBase64,
77+
supplyAPY,
78+
collateralEnabled,
79+
})
80+
}
81+
>
82+
{children ?? <Trans>Supply</Trans>}
83+
</Button>
84+
</>
85+
);
86+
}
87+
88+
export default FunSupplyButton;

0 commit comments

Comments
 (0)