Open jessepinho opened 1 week ago
Latest commit: 0db78a93745e8e56064d9e521528bc25994d3cf6
The changes in this PR will be included in the next version bump.
Not sure what this means? Click here to learn what changesets are.
Click here if you're a maintainer who wants to add another changeset to this PR
Moving back to draft because of merge conflicts that will require a bit of manual resolution
OK @penumbra-zone/web-reviewers — could you please review this now? It got hung up on a rebase that was pretty hefty, and since this has gotten pretty big, it'd be super helpful to get a review soon so I can merge it ASAP. Thanks!
This PR gets rid of our final loader: the IBC Out loader.
The IBC Out loader was responsible for loading and returning balances, asset metadatas, and the staking token metadata. It also was responsible for setting the initial balance selection and chain selection in the IBC Out form's Zustand state.
This PR moves things around a bit so that the IBC Out form can use Zustand entirely:
use[Name]()
hooks.select
property that can be passed touseQuery
. Now, multiple parts of the app can access the same data in state, but reformat it into whatever shape is useful for them using a selector. Of course, whenever the data is updated in any part of the app, the update gets propagated to every part of the app.assets
andbalancesResponses
to theshared
Zustand slice.swap
slice hadswappableAssets
andbalancesResponses
. Similarly, thesend
slice hadtransferableBalancesResponses
. Now that theibcOut
slice also needs to load and use balance responses, all three features (swap, send, and IBC) all use theshared
slice's instance of that data, and use selectors to filter/map/reduce/etc. as needed.stakingTokensAndFilter
ZQuery object. But the data for that object can now be calculated using thebalancesResponses
andstakingTokenMetadata
ZQuery objects in theshared
slice. So I removed thestakingTokensAndFilter
ZQuery object from thestaking
slice, and instead created auseStakingTokensAndFilter()
hook that uses bothshared.balancesResponses
andshared.stakingTokenMetadata
to create the necessary data.Introduce Zustand middlewares.
There are a number of places where we want to mutate the state once e.g., an API call has returned. Previously, we were doing that in the fetcher. For example, in the
send
slice, we'd fetch the balances responses, then setstate.send.selection
to the first balances response before returning the balances responses. Now that multiple minifront features are using data from a singleshared
slice (e.g., the send/swap/ibcOut slices all useshared.balancesResponses
), we needed a way to set certain state values in those other slices in response to theshared
slice updating.In Redux, this would be trivial — we'd just have a reducer that responds to the
SET_BALANCES_RESPONSE
action and updates the state accordingly. But Zustand doesn't have a notion of unique action names, so instead, we have to use middlewares that check the before/after states and determine whether a particular mutation that we care about has taken place.Per Zustand's author, there is no "official" way to create middleware in Zustand. Instead you just literally replace the function passed to
create()
with one that mutatesget
/set
/store
. So that's the approach I took here. I created several middlewares that update other pieces of state once a given piece of state updates. (For example, thesendSelectionMiddleware
updatesstate.send.selection
to the first balances response when it detects thatstate.shared.balancesResponses
has been updated.)main
: #1353 introduced the use of query params to control the swap asset in/out. Unfortunately, rebasing on that PR introduced some serious complications to this PR, so I more or less had to rewrite thesetInitialAssets()
function that was introduced there and use it as a middleware. That added a bit of heft to this PR, which you can see in theswapBalancesMiddleware
.For future PRs, perhaps
use[Name]()
hook from ZQuery triggers a re-fetch, even if the data has already previously been fetched. It'd be great to have a smarter caching/revalidation strategy in the future (probably taking cues from TanStack Query), but that's out of scope for this PR.Closes #1243