-
Notifications
You must be signed in to change notification settings - Fork 272
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: SendProvider #2078
base: main
Are you sure you want to change the base?
feat: SendProvider #2078
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
// AmountInputTypeSwitch uses a skeleton for both loading and error states | ||
// SendAmountInputTypeSwitch uses skeleton for the loading display | ||
// SendAmountInputTypeSwitch uses a custom error display (see loadingDisplay default) | ||
// SendAmountInputTypeSwitch uses skeleton for the loading display but a custom error display (see loadingDisplay default) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the error state is called loadingDisplay?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should let exchangeRateLoading
be handled by AmountInputTypeSwitch
and just return early if there's an error - any reason we can't do that @brendan-defi?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@alessey Yes, right now AmountInputTypeSwitch shows "loadingDisplay" for both loading state and exchange-rate-not-present state:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dschlabach I think I've taken that approach now, let me know what you think
}, | ||
}); | ||
} | ||
setIsInitialized(true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can this be derived?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, good call, this is only based on eth balance right now. refactored in 0cc4028
|
||
const tokenSymbol = selectedToken.symbol; | ||
const tokenAddress = selectedToken.address; | ||
let tokenParam: PriceQuoteToken; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: const tokenParam = selectedToken.symbol === 'ETH' ? 'ETH' : selectedToken.address; if (tokenParam) useExchangeRate()?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated
statusName: 'amountChange', | ||
statusData: { | ||
isMissingRequiredField: true, | ||
sufficientBalance: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hasSufficientBalance? may want to hoist this calculation to the top of this function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hoisted to the top in a memo
@@ -21,7 +26,7 @@ export type SendContextType = { | |||
|
|||
// Sender Context | |||
/** The balance of the sender's ETH wallet */ | |||
ethBalance: number | undefined; | |||
ethBalance: number; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should this have an undefined state to differentiate fetched and 0 from haven't fetched?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, now that we are using this as the derivation scheme, we need an undefined option. updated in 0cc4028
loadingDisplay = ( | ||
<div className={cn(text.caption, color.foregroundMuted, 'h-[1.625rem]')}> | ||
Exchange rate unavailable | ||
</div> | ||
), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think using the tags directly as default props will cause React to re-instantiate them on every render so yhou should probably extract this out to a cmponent
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated how we handle error state
if (errorDisplay) { | ||
return errorDisplay; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can check for this and return earlier in the function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
classNames?: { | ||
container?: string; | ||
tokenName?: string; | ||
tokenValue?: string; | ||
fiatValue?: string; | ||
action?: string; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like all of these classes are applied in the same element. Is it necessary to separate them in the prop definition?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the alternative would be containerClassnames, tokenNameClassnames, etc. right?
i thought the preferred structure for multiple classNames props was an object like this.
...queryOptions, | ||
}; | ||
|
||
const queryKey = ['getPriceQuote', token]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit, don't need to define a variable here just use it in the hook
const [cryptoAmount, setCryptoAmount] = useState<string | null>(null); | ||
|
||
// state for transaction data | ||
const [callData, setCallData] = useState<Call | null>(null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit - calldata is the solidity world so we should just do calldata, setCalldata
useEffect(() => { | ||
fetchTransactionData(); | ||
}, [fetchTransactionData]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you should move this into an internal util hook that uses React Query:
- It'll improve readability by moving fetching logic into its own module
- It'll be easier to handle things like refetching, cache management in case we ever need to tweak those parameters
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
makes sense. does this hook belong in src/transaction?
useEffect(() => { | ||
const ethBalance = tokenBalances?.find((token) => token.address === ''); | ||
if (!ethBalance || ethBalance.cryptoBalance === 0) { | ||
setEthBalance(0); | ||
updateLifecycleStatus({ | ||
statusName: 'fundingWallet', | ||
statusData: { | ||
isMissingRequiredField: true, | ||
}, | ||
}); | ||
return; | ||
} | ||
|
||
setEthBalance( | ||
Number( | ||
formatUnits(BigInt(ethBalance.cryptoBalance), ethBalance.decimals), | ||
), | ||
); | ||
updateLifecycleStatus({ | ||
statusName: 'selectingAddress', | ||
statusData: { | ||
isMissingRequiredField: true, | ||
}, | ||
}); | ||
}, [tokenBalances, updateLifecycleStatus]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like ethBalance
could be derived state (it doesn't feel like it should be a side effect of tokenBalances
loading in).
I wasn't sure what you were doing with the lifecycle statuses here but maybe there's a way to move them somewhere else where it's not a side effect of tokenBalances
either?
What changed? Why?
getPriceQuote
usePriceHook
Notes to reviewers
How has it been tested?