Skip to content
Draft
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
2 changes: 2 additions & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -295,5 +295,7 @@ VITE_FEATURE_CETUS_SWAP=false
VITE_FEATURE_SUNIO_SWAP=false
VITE_FEATURE_MONAD=false
VITE_FEATURE_PLASMA=false

VITE_FEATURE_REFERRAL=false
VITE_HYPEREVM_NODE_URL=https://rpc.hyperliquid.xyz/evm
VITE_FEATURE_HYPEREVM=false
1 change: 1 addition & 0 deletions .env.development
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

# feature flags
VITE_FEATURE_THORCHAIN_TCY_ACTIVITY=true
VITE_FEATURE_REFERRAL=true

# mixpanel
VITE_MIXPANEL_TOKEN=a867ce40912a6b7d01d088cf62b0e1ff
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ export async function getPortalsTradeQuote(
estimatedExecutionTimeMs: isCrossChain ? 300000 : 0,
portalsTransactionMetadata: {
...tx,
orderId: portalsTradeOrderResponse.context.orderId,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👀

isCrossChain,
buyAssetChainId: isCrossChain ? buyAssetChainId : undefined,
expiry: portalsTradeOrderResponse.context.expiry
Expand Down
2 changes: 2 additions & 0 deletions packages/swapper/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@ export type TradeQuoteStep = {
expiry?: number
steps?: string[]
route?: string[]
orderId?: string
}
bebopTransactionMetadata?: {
to: Address
Expand Down Expand Up @@ -448,6 +449,7 @@ export type SwapperSpecificMetadata = {
timeEstimate: number
deadline: string
}
cowswapQuoteSpecific?: OrderQuoteResponse
relayTransactionMetadata: RelayTransactionMetadata | undefined
relayerExplorerTxLink: string | undefined
relayerTxHash: string | undefined
Expand Down
2 changes: 2 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { useFeatureFlag } from '@/hooks/useFeatureFlag/useFeatureFlag'
import { useHasAppUpdated } from '@/hooks/useHasAppUpdated/useHasAppUpdated'
import { useModal } from '@/hooks/useModal/useModal'
import { useNotificationToast } from '@/hooks/useNotificationToast'
import { useReferralCapture } from '@/hooks/useReferralCapture/useReferralCapture'
import { isMobile as isMobileApp } from '@/lib/globals'
import { AppRoutes } from '@/Routes/Routes'

Expand All @@ -35,6 +36,7 @@ export const App = () => {

useAddAccountsGuard()
useAppleSearchAdsAttribution()
useReferralCapture()

useEffect(() => {
if (hasUpdated && !toast.isActive(updateId) && !isActionCenterEnabled) {
Expand Down
37 changes: 36 additions & 1 deletion src/assets/translations/en/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"and": "and",
"balance": "Balance",
"next": "Next",
"actions": "Actions",
"edit": "Edit",
"error": "Error",
"show": "Show",
Expand Down Expand Up @@ -515,7 +516,8 @@
"foxEcosystem": "FOX Ecosystem",
"markets": "Markets",
"tokens": "Tokens",
"swap": "Swap"
"swap": "Swap",
"referral": "Referral"
},
"shapeShiftMenu": {
"products": "Products",
Expand Down Expand Up @@ -2126,6 +2128,39 @@
"emptyBody": "It appears you don't have any loans at the moment. Is this financial zen or just a break before your next big lending adventure? Either way, enjoy the calm!"
}
},
"referral": {
"description": "Earn rewards by referring friends to ShapeShift",
"totalReferrals": "Total Referrals",
"activeCodes": "Active Codes",
"feesCollected": "Fees Collected",
"currentMonth": "Current Month",
"yourReferralLink": "Your Referral Link",
"yourReferralCode": "Your Referral Code",
"currentRewards": "Current Rewards",
"totalRewards": "Total Rewards",
"totalReferred": "Total Referred",
"referrals": "Referrals",
"dashboard": "Dashboard",
"codes": "Codes",
"address": "Address",
"volume": "Volume",
"noCodeYet": "Create a referral code to get your link",
"createNewCode": "Create New Referral Code",
"enterCodeOrLeaveEmpty": "Enter a custom code or leave empty for random",
"random": "Random",
"create": "Create",
"yourCodes": "Your Referral Codes",
"code": "Code",
"usages": "Usages",
"status": "Status",
"createdAt": "Created",
"active": "Active",
"inactive": "Inactive",
"noCodes": "You don't have any referral codes yet. Create your first one above!",
"codeCreated": "Referral Code Created",
"codeCreatedDescription": "Your referral code %{code} has been created successfully",
"createCodeFailed": "Failed to create referral code. Please try again."
},
"chart": {
"interval": {
"5min": "Past five minutes",
Expand Down
35 changes: 32 additions & 3 deletions src/components/Layout/Header/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Box, Divider, Flex, HStack, useMediaQuery } from '@chakra-ui/react'
import { Box, Button, Divider, Flex, HStack, useMediaQuery } from '@chakra-ui/react'
import { useScroll } from 'framer-motion'
import { lazy, memo, Suspense, useCallback, useEffect, useMemo, useRef, useState } from 'react'
import {
Expand All @@ -11,8 +11,9 @@ import {
TbRefresh,
TbStack,
} from 'react-icons/tb'
import { useTranslate } from 'react-polyglot'
import { useSelector } from 'react-redux'
import { useNavigate } from 'react-router-dom'
import { Link as ReactRouterLink, useLocation, useNavigate } from 'react-router-dom'

import { ActionCenter } from './ActionCenter/ActionCenter'
import { DegradedStateBanner } from './DegradedStateBanner'
Expand Down Expand Up @@ -72,10 +73,14 @@ const earnSubMenuItems = [
{ label: 'navBar.lending', path: '/lending', icon: TbBuildingBank },
]

const menuButtonHoverSx = { bg: 'background.surface.elevated' }
const menuButtonActiveSx = { bg: 'transparent' }

export const Header = memo(() => {
const isDegradedState = useSelector(selectPortfolioDegradedState)
const [isLargerThanMd] = useMediaQuery(`(min-width: ${breakpoints['md']})`)

const location = useLocation()
const translate = useTranslate()
const navigate = useNavigate()
const {
state: { isConnected, walletInfo },
Expand Down Expand Up @@ -111,6 +116,7 @@ export const Header = memo(() => {
const isWalletConnectToDappsV2Enabled = useFeatureFlag('WalletConnectToDappsV2')
const isActionCenterEnabled = useFeatureFlag('ActionCenter')
const isNewWalletManagerEnabled = useFeatureFlag('NewWalletManager')
const isReferralEnabled = useFeatureFlag('Referral')
const { degradedChainIds } = useDiscoverAccounts()

const hasWallet = Boolean(walletInfo?.deviceId)
Expand Down Expand Up @@ -170,6 +176,29 @@ export const Header = memo(() => {
defaultPath='/assets'
/>
<NavigationDropdown label='defi.earn' items={earnSubMenuItems} defaultPath='/tcy' />
{isReferralEnabled && (
<Button
as={ReactRouterLink}
to='/fox-ecosystem'
variant='ghost'
fontWeight='medium'
px={3}
py={2}
borderRadius='md'
_hover={menuButtonHoverSx}
_active={menuButtonActiveSx}
aria-current={location.pathname.startsWith('/fox-ecosystem') ? 'page' : undefined}
>
<Box
fontSize='md'
color={
location.pathname.startsWith('/fox-ecosystem') ? 'text.base' : 'text.subtle'
}
>
{translate('navBar.referral')}
</Box>
</Button>
)}
</HStack>
</HStack>

Expand Down
68 changes: 68 additions & 0 deletions src/components/Referral/CreateCodeCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { Button, Card, CardBody, CardHeader, Heading, HStack, Input } from '@chakra-ui/react'
import { FaPlus } from 'react-icons/fa'
import { useTranslate } from 'react-polyglot'

type CreateCodeCardProps = {
newCodeInput: string
isCreating: boolean
onInputChange: (value: string) => void
onGenerateRandom: () => void
onCreate: () => void
}

export const CreateCodeCard = ({
newCodeInput,
isCreating,
onInputChange,
onGenerateRandom,
onCreate,
}: CreateCodeCardProps) => {
const translate = useTranslate()

return (
<Card
bg='background.surface.raised.base'
borderRadius='xl'
borderTop='1px solid'
borderColor='gray.700'
py={2}
>
<CardHeader>
<Heading size='md'>{translate('referral.createNewCode')}</Heading>
</CardHeader>
<CardBody>
<HStack>
<Input
value={newCodeInput}
onChange={e => onInputChange(e.target.value.toUpperCase())}
placeholder={translate('referral.enterCodeOrLeaveEmpty')}
maxLength={20}
bg='background.surface.raised.base'
border='none'
/>
<Button
onClick={onGenerateRandom}
leftIcon={<FaPlus />}
variant='outline'
flexShrink={0}
borderRadius='full'
border='1px solid'
borderColor='gray.700'
backgroundColor='background.surface.raised.base'
>
{translate('referral.random')}
</Button>
<Button
onClick={onCreate}
colorScheme='blue'
isLoading={isCreating}
flexShrink={0}
borderRadius='full'
>
{translate('referral.create')}
</Button>
</HStack>
Comment on lines +13 to +64
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Sanitize referral-code input to expected charset (avoid create failures on spaces/symbols)
Uppercasing alone still allows invalid characters; this will push avoidable errors into the create mutation.

 import { FaPlus } from 'react-icons/fa'
 import { useTranslate } from 'react-polyglot'

+const normalizeReferralCodeInput = (value: string): string => {
+  return value.toUpperCase().replace(/[^A-Z0-9]/g, '').slice(0, 20)
+}
+
 type CreateCodeCardProps = {
   newCodeInput: string
   isCreating: boolean
   onInputChange: (value: string) => void
@@
           <Input
             value={newCodeInput}
-            onChange={e => onInputChange(e.target.value.toUpperCase())}
+            onChange={e => onInputChange(normalizeReferralCodeInput(e.target.value))}
             placeholder={translate('referral.enterCodeOrLeaveEmpty')}
             maxLength={20}
             bg='background.surface.raised.base'
             border='none'
           />
🤖 Prompt for AI Agents
In src/components/Referral/CreateCodeCard.tsx around lines 13 to 64, the input
onChange only uppercases the value but still allows spaces and symbols which
cause backend create failures; update the onChange handler to sanitize the value
by removing all characters outside the expected charset (e.g. allow only A–Z and
0–9, optionally dash/underscore if required), strip whitespace and symbols, then
uppercase the result and pass that sanitized string to onInputChange; keep
maxLength and consider also trimming on paste or validating before calling
onCreate so the Create button cannot submit invalid input.

</CardBody>
</Card>
)
}
83 changes: 83 additions & 0 deletions src/components/Referral/ReferralCodeCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { Card, CardBody, Flex, Heading, IconButton, Skeleton, Text } from '@chakra-ui/react'
import { FaCopy } from 'react-icons/fa'
import { FaXTwitter } from 'react-icons/fa6'
import { useTranslate } from 'react-polyglot'

type ReferralCodeCardProps = {
code: string | null
isLoading: boolean
onShareOnX: (code: string) => void
onCopyCode: (code: string) => void
}

export const ReferralCodeCard = ({
code,
isLoading,
onShareOnX,
onCopyCode,
}: ReferralCodeCardProps) => {
const translate = useTranslate()

if (isLoading) {
return (
<Card
color='white'
borderRadius='2xl'
overflow='hidden'
width='50%'
borderTop='1px solid'
borderColor='gray.700'
>
<CardBody px={6} py={4} display='flex' alignItems='center'>
<Skeleton height='60px' width='full' />
</CardBody>
</Card>
)
}

return (
<Card
color='white'
borderRadius='2xl'
overflow='hidden'
width='50%'
borderTop='1px solid'
borderColor='gray.700'
>
<CardBody px={6} py={4} display='flex' alignItems='center'>
<Flex alignItems='center' justifyContent='space-between' width='full'>
<Flex flexDirection='column' gap={0}>
<Text fontSize='md' opacity={0.7} mb={1}>
{translate('referral.yourReferralCode')}
</Text>
<Heading size='xl' fontWeight='bold' letterSpacing='wide'>
{code || 'N/A'}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Use translation key for fallback text.

The hardcoded 'N/A' should use a translation key for i18n support. As per coding guidelines, all copy/text must use translation keys.

-              {code || 'N/A'}
+              {code || translate('common.notAvailable')}

Note: You may need to add common.notAvailable to the translations file if it doesn't exist.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/components/Referral/ReferralCodeCard.tsx around line 54 the fallback text
'N/A' is hardcoded; replace it with the i18n translation key (e.g.
t('common.notAvailable')) and ensure useTranslation is imported and used in the
component (or t is available via props/context). Also add the key
common.notAvailable to the translations JSON for supported locales if it doesn't
exist so the fallback displays correctly.

</Heading>
</Flex>
{code && (
<Flex alignItems='center' gap={2}>
<IconButton
aria-label='Share on X'
icon={<FaXTwitter />}
size='md'
colorScheme='whiteAlpha'
borderRadius='100%'
bg='whiteAlpha.200'
onClick={() => onShareOnX(code)}
/>
<IconButton
aria-label='Copy link'
icon={<FaCopy />}
size='md'
colorScheme='whiteAlpha'
bg='whiteAlpha.200'
borderRadius='100%'
onClick={() => onCopyCode(code)}
/>
Comment on lines +59 to +76
Copy link
Contributor

@coderabbitai coderabbitai bot Dec 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Use translation keys for aria-labels.

The aria-labels are hardcoded in English, which affects accessibility for non-English users. As per coding guidelines, all text should use translation keys.

               <IconButton
-                aria-label='Share on X'
+                aria-label={translate('common.shareOnX')}
                 icon={<FaXTwitter />}
                 size='md'
                 colorScheme='whiteAlpha'
                 borderRadius='100%'
                 bg='whiteAlpha.200'
                 onClick={() => onShareOnX(code)}
               />
               <IconButton
-                aria-label='Copy link'
+                aria-label={translate('common.copy')}
                 icon={<FaCopy />}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<IconButton
aria-label='Share on X'
icon={<FaXTwitter />}
size='md'
colorScheme='whiteAlpha'
borderRadius='100%'
bg='whiteAlpha.200'
onClick={() => onShareOnX(code)}
/>
<IconButton
aria-label='Copy link'
icon={<FaCopy />}
size='md'
colorScheme='whiteAlpha'
bg='whiteAlpha.200'
borderRadius='100%'
onClick={() => onCopyCode(code)}
/>
<IconButton
aria-label={translate('common.shareOnX')}
icon={<FaXTwitter />}
size='md'
colorScheme='whiteAlpha'
borderRadius='100%'
bg='whiteAlpha.200'
onClick={() => onShareOnX(code)}
/>
<IconButton
aria-label={translate('common.copy')}
icon={<FaCopy />}
size='md'
colorScheme='whiteAlpha'
bg='whiteAlpha.200'
borderRadius='100%'
onClick={() => onCopyCode(code)}
/>
🤖 Prompt for AI Agents
In src/components/Referral/ReferralCodeCard.tsx around lines 59 to 76 the
aria-label props are hardcoded in English; replace them with translation keys
using your i18n hook (e.g., import and call useTranslation or t) and pass
t('referral.share_on_x') for the Share on X button and t('referral.copy_link')
for the Copy link button (or the exact keys from your locale files), ensuring
the translation hook is imported and used in the component and the aria-label
props receive the translated strings.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tbh we don't care about aria-labels so meh

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gomesalexandre, understood! I'll skip aria-label suggestions for this codebase going forward.


🧠 Learnings used
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10323
File: src/components/Layout/Header/ActionCenter/components/RewardDistributionActionCard.tsx:26-29
Timestamp: 2025-08-22T12:59:01.210Z
Learning: In src/components/Layout/Header/ActionCenter/components/RewardDistributionActionCard.tsx, NeOMakinG declined wrapping the RewardDistributionActionCard component with React.memo, saying it was "too much", suggesting that like other action center components, memoization is not beneficial for this specific use case.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10418
File: src/plugins/walletConnectToDapps/components/header/WalletConnectToDappsHeaderButton.tsx:0-0
Timestamp: 2025-09-08T22:00:48.005Z
Learning: gomesalexandre dismissed an aria-label accessibility suggestion with "meh" in PR #10418 for WalletConnectToDappsHeaderButton.tsx, consistent with the team's pattern of deferring minor a11y improvements to follow-up PRs rather than expanding feature PR scope.

Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10231
File: src/components/AssetSearch/components/AssetList.tsx:2-2
Timestamp: 2025-08-08T15:00:49.887Z
Learning: Project shapeshift/web: NeOMakinG prefers avoiding minor a11y/UI nitpicks (e.g., adding aria-hidden to decorative icons in empty states like src/components/AssetSearch/components/AssetList.tsx) within feature PRs; defer such suggestions to a follow-up instead of blocking the PR.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10458
File: src/plugins/walletConnectToDapps/components/modals/EIP155SignTypedDataConfirmation.tsx:69-74
Timestamp: 2025-09-10T15:35:36.547Z
Learning: gomesalexandre dismissed alt text accessibility suggestion with "meh" in PR #10458 for EIP155SignTypedDataConfirmation.tsx Image component, consistent with team pattern of deferring minor a11y improvements to follow-up PRs rather than expanding feature PR scope.

Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to **/*.{ts,tsx} : All copy/text must use translation keys - never hardcode strings

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10490
File: src/components/Layout/Header/NavBar/ShapeShiftMenu.tsx:0-0
Timestamp: 2025-09-16T09:32:14.405Z
Learning: gomesalexandre dismissed keyboard accessibility suggestion for hover dropdown in ShapeShiftMenu.tsx by referencing his previous comment on NavigationDropdown.tsx where he said "meh keyboard, it's a hover dropdown, how are you going to see it with keyboard nav? sry vimium users", consistent with his pattern of deferring minor a11y improvements to keep PR scope focused.

Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10231
File: src/pages/Explore/ExploreCategory.tsx:231-238
Timestamp: 2025-08-08T14:59:40.422Z
Learning: In src/pages/Explore/ExploreCategory.tsx, for the PageHeader filter trigger, NeOMakinG considers changing a clickable Chakra Icon to IconButton too nitpicky for this PR and prefers to keep the current Icon-based trigger; such minor a11y/UI nitpicks should be deferred to a follow-up if needed.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10490
File: src/components/Layout/Header/NavBar/ShapeShiftMenu.tsx:0-0
Timestamp: 2025-09-16T09:32:14.405Z
Learning: gomesalexandre dismissed keyboard accessibility suggestion for hover dropdown in ShapeShiftMenu.tsx, referencing his previous comment about hover dropdowns not being suitable for keyboard navigation and apologizing to "vimium users", consistent with his pattern of deferring minor a11y improvements to keep PR scope focused.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10187
File: src/assets/translations/en/main.json:205-206
Timestamp: 2025-08-06T08:58:09.096Z
Learning: gomesalexandre considers translation key consolidation (like multiple keys for "view on explorer" functionality) as nice-to-have improvements rather than critical issues. The team doesn't prioritize i18n consistency across the board currently, and they prefer to handle such consolidation suggestions at their own discretion based on other priorities.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10490
File: src/components/Layout/Header/NavBar/NavigationDropdown.tsx:75-90
Timestamp: 2025-09-16T09:31:15.378Z
Learning: gomesalexandre dismissed keyboard accessibility suggestion for hover dropdown in NavigationDropdown.tsx, noting that hover dropdowns aren't suitable for keyboard navigation and apologizing to "vimium users", consistent with his pattern of deferring minor a11y improvements to keep PR scope focused.

Learnt from: premiumjibles
Repo: shapeshift/web PR: 10361
File: src/pages/Markets/components/CardWithSparkline.tsx:83-92
Timestamp: 2025-08-25T23:32:13.876Z
Learning: In shapeshift/web PR #10361, premiumjibles considered the nested button accessibility issue (ChartErrorFallback retry Button inside Card rendered as Button in CardWithSparkline.tsx) out of scope for the error boundaries feature PR, consistent with deferring minor a11y improvements to follow-up PRs.

Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10272
File: src/components/StarRating/StarRating.tsx:12-0
Timestamp: 2025-08-13T15:52:06.578Z
Learning: In the ShapeShift web codebase, NeOMakinG and the team generally do not prioritize ARIA attributes and accessibility enhancements for interactive components. They prefer to avoid adding accessibility features like role, tabIndex, aria-label, or keyboard handlers to components, even for user-facing interactive elements like star rating systems.

Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10323
File: src/components/Layout/Header/ActionCenter/components/RewardDistributionActionCard.tsx:37-53
Timestamp: 2025-08-22T12:59:01.702Z
Learning: In RewardDistributionActionCard component (src/components/Layout/Header/ActionCenter/components/RewardDistributionActionCard.tsx), NeOMakinG confirmed that runeAsset is expected to always be defined when the component renders, so defensive guards against undefined runeAsset are not needed.

Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10191
File: src/pages/Explore/components/CategoryCard.tsx:27-196
Timestamp: 2025-08-06T09:46:50.860Z
Learning: In src/pages/Explore/components/CategoryCard.tsx, NeOMakinG indicated that wrapping the CategoryCard component with React.memo would be "quite useless in this case", suggesting that memoization is not beneficial for this particular component despite it receiving props, likely due to its specific usage patterns or context.

Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to **/*.{ts,tsx} : Use Chakra UI components and conventions

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10206
File: src/config.ts:127-128
Timestamp: 2025-08-07T11:20:44.614Z
Learning: gomesalexandre prefers required environment variables without default values in the config file (src/config.ts). They want explicit configuration and fail-fast behavior when environment variables are missing, rather than having fallback defaults.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/ContractInteractionBreakdown.tsx:0-0
Timestamp: 2025-09-13T16:45:18.813Z
Learning: gomesalexandre prefers aggressively deleting unused/obsolete code files ("ramboing") rather than fixing technical issues in code that won't be used, demonstrating his preference for keeping codebases clean and PR scope focused.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10458
File: src/plugins/walletConnectToDapps/types.ts:7-7
Timestamp: 2025-09-10T15:34:29.604Z
Learning: gomesalexandre is comfortable relying on transitive dependencies (like abitype through ethers/viem) rather than explicitly declaring them in package.json, preferring to avoid package.json bloat when the transitive dependency approach works reliably in practice.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10503
File: .env:56-56
Timestamp: 2025-09-16T13:17:02.938Z
Learning: gomesalexandre prefers to enable feature flags globally in the base .env file when the intent is to activate features everywhere, even when there are known issues like crashes, demonstrating his preference for intentional global feature rollouts over cautious per-environment enablement.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10249
File: src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx:447-503
Timestamp: 2025-08-13T17:07:10.763Z
Learning: gomesalexandre prefers relying on TypeScript's type system for validation rather than adding defensive runtime null checks when types are properly defined. They favor a TypeScript-first approach over defensive programming with runtime validations.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10276
File: src/hooks/useActionCenterSubscribers/useThorchainLpDepositActionSubscriber.tsx:61-66
Timestamp: 2025-08-14T17:51:47.556Z
Learning: gomesalexandre is not concerned about structured logging and prefers to keep console.error usage as-is rather than implementing structured logging patterns, even when project guidelines suggest otherwise.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10413
File: src/components/Modals/FiatRamps/fiatRampProviders/onramper/utils.ts:29-55
Timestamp: 2025-09-02T14:26:19.028Z
Learning: gomesalexandre prefers to keep preparatory/reference code simple until it's actively consumed, rather than implementing comprehensive error handling, validation, and robustness improvements upfront. They prefer to add these improvements when the code is actually being used in production.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10276
File: src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx:396-402
Timestamp: 2025-08-14T17:55:57.490Z
Learning: gomesalexandre is comfortable with functions/variables that return undefined or true (tri-state) when only the truthy case matters, preferring to rely on JavaScript's truthy/falsy behavior rather than explicitly returning boolean values.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10783
File: src/context/ModalStackProvider/useModalRegistration.ts:30-41
Timestamp: 2025-10-16T11:14:40.657Z
Learning: gomesalexandre prefers to add lint rules (like typescript-eslint/strict-boolean-expressions for truthiness checks on numbers) to catch common issues project-wide rather than relying on code review to catch them.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10206
File: src/lib/moralis.ts:47-85
Timestamp: 2025-08-07T11:22:16.983Z
Learning: gomesalexandre prefers console.error over structured logging for Moralis API integration debugging, as they find it more conventional and prefer to examine XHR requests directly rather than rely on structured logs for troubleshooting.

Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10231
File: src/components/MultiHopTrade/components/TradeInput/components/HighlightedTokens.tsx:14-14
Timestamp: 2025-08-08T15:00:22.321Z
Learning: In shapeshift/web reviews for NeOMakinG, avoid nitpicks to change deep-relative imports to '@/…' alias paths within feature/non-refactor PRs; defer such style-only changes to a dedicated follow-up refactor unless they fix an issue.

</Flex>
)}
</Flex>
</CardBody>
</Card>
)
}
Loading
Loading