Skip to content
This repository was archived by the owner on Aug 26, 2025. It is now read-only.

Commit 12eb371

Browse files
authored
Merge branch 'main' into dev
2 parents 0fd0fe0 + 699ec1a commit 12eb371

File tree

16 files changed

+567
-261
lines changed

16 files changed

+567
-261
lines changed

.github/workflows/check-branch.yml

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,24 @@
1-
name: Prevent Non-Release/Non-Hotfix PRs to Main
1+
# NOTE: @chapati23 disabled this check today on 18.02.2025 as a conscious tradeoff to prioritize simpler and faster delivery
2+
# over a slower release cycle with more checks. We can turn it back on if we notice that we have more production issues but
3+
# for the moment we don't have a lot of users on this DApp so should prioritize faster improvements until we reach greater scale.
24

3-
on:
4-
pull_request:
5-
branches:
6-
- main
7-
pull_request_target:
8-
branches:
9-
- main
5+
# name: Prevent Non-Release/Non-Hotfix PRs to Main
6+
# on:
7+
# pull_request:
8+
# branches:
9+
# - main
10+
# pull_request_target:
11+
# branches:
12+
# - main
1013

11-
jobs:
12-
check-target-branch:
13-
if: github.base_ref == 'main'
14-
runs-on: ubuntu-latest
15-
steps:
16-
- name: Check if the source branch is a release branch
17-
run: |
18-
if [[ "${{ github.head_ref }}" != release/* && "${{ github.head_ref }}" != hotfix/* ]]; then
19-
echo "Only release and hotfix branches can be merged into the main branch."
20-
exit 1
21-
fi
14+
# jobs:
15+
# check-target-branch:
16+
# if: github.base_ref == 'main'
17+
# runs-on: ubuntu-latest
18+
# steps:
19+
# - name: Check if the source branch is a release branch
20+
# run: |
21+
# if [[ "${{ github.head_ref }}" != release/* && "${{ github.head_ref }}" != hotfix/* ]]; then
22+
# echo "Only release and hotfix branches can be merged into the main branch."
23+
# exit 1
24+
# fi

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@mento-protocol/mento-web",
3-
"version": "2.3.6",
3+
"version": "2.3.7",
44
"description": "A simple DApp for Celo Mento exchanges",
55
"keywords": [
66
"Celo",
@@ -29,7 +29,7 @@
2929
"@celo/rainbowkit-celo": "^0.11.0",
3030
"@headlessui-float/react": "^0.11.2",
3131
"@headlessui/react": "^1.7.13",
32-
"@mento-protocol/mento-sdk": "^1.0.2",
32+
"@mento-protocol/mento-sdk": "^1.0.3",
3333
"@metamask/jazzicon": "https://github.com/jmrossy/jazzicon#7a8df28",
3434
"@metamask/post-message-stream": "6.1.2",
3535
"@metamask/providers": "10.2.1",

src/components/buttons/3DButton.tsx

Lines changed: 81 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,39 +2,104 @@ import { PropsWithChildren } from 'react'
22

33
type BaseButtonProps = {
44
onClick?: () => void
5-
error?: boolean
6-
fullWidth?: boolean
75
type?: 'button' | 'submit' | 'reset'
6+
isError?: boolean
7+
isFullWidth?: boolean
8+
isDisabled?: boolean
9+
isWalletConnected?: boolean
10+
isBalanceLoaded?: boolean
811
}
912

10-
export const Button3D = ({ children, ...restProps }: PropsWithChildren<BaseButtonProps>) => {
11-
return <_3DButtonLink {...restProps}>{children}</_3DButtonLink>
13+
export enum Button3DText {
14+
connectWallet = 'Connect Wallet',
15+
continue = 'Continue',
16+
balanceStillLoading = 'Balance still loading...',
17+
switchToCeloNetwork = 'Switch to Celo Network',
1218
}
1319

14-
const _3DButtonLink = ({
20+
export const Button3D = ({
1521
children,
16-
error,
17-
fullWidth,
1822
onClick,
19-
type,
23+
type = 'button',
24+
isError,
25+
isFullWidth,
26+
isDisabled,
27+
isWalletConnected,
28+
isBalanceLoaded,
2029
}: PropsWithChildren<BaseButtonProps>) => {
2130
return (
22-
<button className={fullWidth ? 'w-full' : ''} onClick={onClick} type={type ?? 'button'}>
31+
<button
32+
className={isFullWidth ? 'w-full' : ''}
33+
onClick={onClick}
34+
type={type}
35+
disabled={isDisabled}
36+
>
2337
<span
24-
className={`group font-inter outline-offset-4 cursor-pointer ${
25-
error ? 'bg-[#863636]' : 'bg-[#2A326A]'
26-
} ${
27-
fullWidth ? 'w-full ' : ''
38+
className={`group font-inter outline-offset-4 cursor-pointer ${getShadowButtonColor({
39+
isDisabled,
40+
isWalletConnected,
41+
isError,
42+
isBalanceLoaded,
43+
})} ${
44+
isFullWidth ? 'w-full ' : ''
2845
} border-b rounded-lg border-primary-dark font-medium select-none inline-block`}
2946
>
3047
<span
31-
className={`${'pr-10'} pl-10 group-active:-translate-y-[2px] block py-[18px] transition-transform delay-[250] hover:-translate-y-[6px] -translate-y-[4px] font-medium text-[15px] border rounded-lg border-primary-dark leading-5 ${
32-
error ? 'bg-[#E14F4F] text-white' : 'bg-[#4D62F0] text-white '
33-
} ${fullWidth ? 'w-full flex items-center justify-center' : ''} `}
48+
className={`pr-10 pl-10 group-active:-translate-y-[2px] block py-[18px] transition-transform delay-[250] hover:translate-y-[${
49+
isDisabled ? '-4px' : '6px'
50+
}] -translate-y-[4px] font-medium text-[15px] border rounded-lg border-primary-dark leading-5 ${getButtonColor(
51+
{
52+
isDisabled,
53+
isWalletConnected,
54+
isError,
55+
isBalanceLoaded,
56+
}
57+
)} ${isFullWidth ? 'w-full flex items-center justify-center' : ''} `}
3458
>
3559
<span className="flex items-center">{children}</span>
3660
</span>
3761
</span>
3862
</button>
3963
)
4064
}
65+
66+
function getShadowButtonColor({
67+
isDisabled,
68+
isWalletConnected,
69+
isError,
70+
isBalanceLoaded,
71+
}: IGetButtonColorArgs) {
72+
switch (true) {
73+
case isDisabled:
74+
case isWalletConnected && !isBalanceLoaded:
75+
return 'bg-[#666666]'
76+
case isError && isWalletConnected:
77+
return 'bg-[#863636]'
78+
default:
79+
return 'bg-[#2A326A]'
80+
}
81+
}
82+
83+
function getButtonColor({
84+
isDisabled,
85+
isWalletConnected,
86+
isError,
87+
isBalanceLoaded,
88+
}: IGetButtonColorArgs) {
89+
switch (true) {
90+
case isDisabled:
91+
case isWalletConnected && !isBalanceLoaded:
92+
return 'bg-[#888888] text-white cursor-not-allowed'
93+
case isError && isWalletConnected:
94+
return 'bg-[#E14F4F] text-white'
95+
default:
96+
return 'bg-[#4D62F0] text-white '
97+
}
98+
}
99+
100+
interface IGetButtonColorArgs {
101+
isWalletConnected: boolean | undefined
102+
isBalanceLoaded: boolean | undefined
103+
isDisabled: boolean | undefined
104+
isError: boolean | undefined
105+
}

src/components/nav/BottomGrid.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import BackgroundTiles from 'src/images/background/background_tiles_light.png'
44

55
export function BottomGrid() {
66
return (
7-
<div className="absolute bottom-0 z-10 transform -translate-x-1/2 left-1/2">
7+
<div className="absolute bottom-0 transform -translate-x-1/2 left-1/2 pointer-events-none">
88
<div className="w-screen h-[201px] relative">
99
<Image
1010
src={BackgroundTiles}

src/components/tooltip/Tooltip.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export const Tooltip = ({ text, dataTestId = 'tooltipText' }: TooltipProps) => (
2+
<div className="absolute bottom-[-150%] transform -translate-x-[30%] bg-[rgb(29,29,32)] text-white text-xs rounded-md px-2 py-1 opacity-0 group-hover:opacity-100 transition-opacity z-10">
3+
<span datatest-id={dataTestId}>{text}</span>
4+
</div>
5+
)
6+
7+
interface TooltipProps {
8+
text: string
9+
dataTestId?: string
10+
}

src/config/tokens.ts

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export enum TokenId {
2828
cKES = 'cKES',
2929
PUSO = 'PUSO',
3030
cCOP = 'cCOP',
31+
cGHS = 'cGHS',
3132
}
3233

3334
export const NativeStableTokenIds = [TokenId.cUSD, TokenId.cEUR, TokenId.cREAL]
@@ -122,6 +123,14 @@ export const cCOP: Token = Object.freeze({
122123
decimals: 18,
123124
})
124125

126+
export const cGHS: Token = Object.freeze({
127+
id: TokenId.cGHS,
128+
symbol: TokenId.cGHS,
129+
name: 'cGHS',
130+
color: Color.usdcBlue,
131+
decimals: 18,
132+
})
133+
125134
export const Tokens: Record<TokenId, Token> = {
126135
CELO,
127136
cUSD,
@@ -135,6 +144,7 @@ export const Tokens: Record<TokenId, Token> = {
135144
cKES,
136145
PUSO,
137146
cCOP,
147+
cGHS,
138148
}
139149

140150
export const TokenAddresses: Record<ChainId, Record<TokenId, Address>> = Object.freeze({
@@ -151,6 +161,7 @@ export const TokenAddresses: Record<ChainId, Record<TokenId, Address>> = Object.
151161
[TokenId.cKES]: '0x1E0433C1769271ECcF4CFF9FDdD515eefE6CdF92',
152162
[TokenId.PUSO]: '0x5E0E3c9419C42a1B04e2525991FB1A2C467AB8bF',
153163
[TokenId.cCOP]: '0xe6A57340f0df6E020c1c0a80bC6E13048601f0d4',
164+
[TokenId.cGHS]: '0xf419dfab059c36cbafb43a088ebeb2811f9789b9',
154165
},
155166
[ChainId.Baklava]: {
156167
[TokenId.CELO]: '0xdDc9bE57f553fe75752D61606B94CBD7e0264eF8',
@@ -165,6 +176,7 @@ export const TokenAddresses: Record<ChainId, Record<TokenId, Address>> = Object.
165176
[TokenId.cKES]: '0x8813Ae180017057d0Cf98C930cED1E7101B97370',
166177
[TokenId.PUSO]: '',
167178
[TokenId.cCOP]: '',
179+
[TokenId.cGHS]: '',
168180
},
169181
[ChainId.Celo]: {
170182
[TokenId.CELO]: '0x471EcE3750Da237f93B8E339c536989b8978a438',
@@ -179,6 +191,7 @@ export const TokenAddresses: Record<ChainId, Record<TokenId, Address>> = Object.
179191
[TokenId.cKES]: '0x456a3D042C0DbD3db53D5489e98dFb038553B0d0',
180192
[TokenId.PUSO]: '0x105d4A9306D2E55a71d2Eb95B81553AE1dC20d7B',
181193
[TokenId.cCOP]: '0x8A567e2aE79CA692Bd748aB832081C45de4041eA',
194+
[TokenId.cGHS]: '0xfAeA5F3404bbA20D3cc2f8C4B0A888F55a3c7313',
182195
},
183196
})
184197

@@ -203,10 +216,20 @@ export async function isSwappable(token_1: string, token_2: string, chainId: num
203216
)
204217
}
205218

206-
export function getSwappableTokenOptions(token: string, chainId: ChainId) {
207-
return getTokenOptionsByChainId(chainId)
208-
.filter((tkn) => isSwappable(tkn, token, chainId))
209-
.filter((tkn) => token !== tkn)
219+
export async function getSwappableTokenOptions(token: string, chainId: ChainId) {
220+
const options = getTokenOptionsByChainId(chainId)
221+
222+
const swappableOptions = await Promise.all(
223+
options.map(async (tkn) => ({
224+
token: tkn,
225+
isSwappable: await isSwappable(tkn, token, chainId),
226+
}))
227+
).then((results) => {
228+
return results
229+
.filter((result) => result.isSwappable && result.token !== token)
230+
.map((result) => result.token)
231+
})
232+
return swappableOptions
210233
}
211234

212235
export function getTokenOptionsByChainId(chainId: ChainId): TokenId[] {
@@ -219,8 +242,8 @@ export function getTokenOptionsByChainId(chainId: ChainId): TokenId[] {
219242
: []
220243
}
221244

222-
export function getTokenById(id: string): Token | null {
223-
return Tokens[id as TokenId] || null
245+
export function getTokenById(id: TokenId | string): Token {
246+
return Tokens[id as TokenId]
224247
}
225248

226249
export function getTokenAddress(id: TokenId, chainId: ChainId): Address {

0 commit comments

Comments
 (0)