Skip to content
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

refactor: Include logger and sendPayment in useWallets #1643

Closed
wants to merge 7 commits into from

Conversation

ekzyis
Copy link
Member

@ekzyis ekzyis commented Nov 23, 2024

Description

This is a prerequisite for #1642.

Since for #1642, useWallets needs to return wallets with the functionality to pay, I updated the code so we include the payment interface in useWallets.

Since the payment interface requires the wallet logger, I call the logger hooks for each wallet (useWalletLogger) in a loop even though that is against the rules of hooks. To prevent calling hooks in a different order between renders, I am sorting wallets by name before I call the hooks and independent of their priority or if they are even configured.

Based on #1638, #1640, #1641

Additional Context

tbd

Checklist

Are your changes backwards compatible? Please answer below:

yes, useWallet continues to work as before

On a scale of 1-10 how well and how have you QA'd this change and any features it might affect? Please answer below:

tbd

For frontend changes: Tested on mobile, light and dark mode? Please answer below:

n/a

Did you introduce any new environment variables? If so, call them out explicitly here:

no

@ekzyis ekzyis marked this pull request as draft November 23, 2024 05:31
@ekzyis ekzyis mentioned this pull request Nov 23, 2024
18 tasks
.reduce((acc, w) => {
return {
...acc,
[w.def.name]: useWalletLogger(w.def)?.logger
Copy link
Member

Choose a reason for hiding this comment

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

Usually, this can be avoided by refactoring non-hook stuff out of the hook.

My initial refactor of this code had to do this a lot.


It's also going to be tempting to start making useWallets a monolith again, but that's part of what made the code so buggy. Meaning, it's going to be convenient to push all code into useWallets for anything that uses useWallets but it's going to be inconvenient to maintain.

Screenshot 2024-11-23 at 1 30 11 PM

Copy link
Member

@huumn huumn Nov 23, 2024

Choose a reason for hiding this comment

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

Another thing that might help is figuring out a new pattern for dealing with a hook that returns an array.

currently:

function MyComponent () => {
const wallets = useWallets()
return wallets.map(...)
}
// or
function useSomethingWithAWallet () => {
const wallets = useWallets()
const [state, setState] = useState()

const cb = useCallback(..., [wallets, state])

return cb
}

Our desire seems to be to want to "decorate" a dynamically chosen wallet from useWallets, but we usually do that in a hook for a single wallet, e.g. useWalletLogger.

That's not a super complete picture, but if we enumerate all the problems we're trying to solve, we should be able to come up with an acceptable pattern to deal with this.

Copy link
Member Author

@ekzyis ekzyis Nov 24, 2024

Choose a reason for hiding this comment

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

These are my high-level thoughts:


Current problem

useWallets returns an array of wallet configurations which cannot pay.

For sender fallbacks, we need an array of wallets that can pay.

waitForWalletPayment requires a wallet that can pay.

We cannot add the payment interface in waitForWalletPayment to a wallet because this means the wallet needs to be set when we call useWalletPayment else we would call a hook inside a function call and not in the top-level of a React component. And we cannot set the wallet when we call useWalletPayment because we want to use multiple wallets, not just one.

wallet.sendPayment requires the logger which requires to call the useWalletLogger hook.


First idea: path of least resistance

  • add payment interface in useWallets and thus call useWalletLogger in there, too

Problem: useWallets tends to become a buggy, hard-to-maintain monolith again

Status: DISMISSED


Second idea: move code around + better naming

  • rename following stuff:
    • WalletsProvider -> WalletConfigsProvider
    • useWallets -> useWalletConfigs
    • useWallet -> useWalletConfig

Since useWallets doesn't return a wallet that can pay but (decrypted) configurations of wallets (which lead me to believe we should add the payment interface there), I think that rename would be a good decision.

  • create new useWallets(configs) hook that requires the array of wallet configs and then adds the payment interface to them. We then loop over this for sender fallbacks and pass each wallet to waitForWalletPayment.

  • create new useWallet that calls the new useWallets and filters the wallet we want out (just like it does currently)

Problem: ???

Status: OPEN


Third idea: make useWalletPayment aware of wallet array

  • keep useWallets as-is (prior to this PR) and replace useWalletPayment with something that wraps useWallets and returns wallets with the payment interface like I did in this PR (= useWalletPayments). We then loop over this and can call wallet.sendPayment directly (which already includes the logging code).

Problem: ??? (except that useWallets is still a bad name imo)

Status: OPEN


Fourth idea: decouple loggers from wallets

  • replace useWalletLogger with useWalletLoggers which returns an array of wallet loggers. I think useWalletLogger doesn't need to know much about a wallet, we could run the little code that we need from useWallets in useWalletLoggers, too.

  • merge the arrays returned by useWallets and useWalletLoggers in a new hook to return an array of wallets with the payment interface

Problem: see below

Status: OPEN


Fifth idea: a mix of all ideas

Not much to say here. Just a filler option to acknowledge that there might be something good in each idea and to make the picture below a better fit.

Status: OPEN


In all ideas except the fourth one, we need to call useWalletLogger in a for loop that doesn't break the rules of hooks (= consistent order between renders). However, I don't really like the fourth idea. I prefer mapping and filtering over merging arrays. Additionally, I think only using walletDefs in one place (useWallets) is better than also using it in useWalletLoggers to pick out of it what we need without calling useWallets.

2024-11-24-192941_1920x1080_scrot

Copy link
Member

Choose a reason for hiding this comment

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

Second idea: move code around + better naming

I think this one is the winner. It sounds like we just need to start composing hooks.

Copy link
Member Author

@ekzyis ekzyis Nov 24, 2024

Choose a reason for hiding this comment

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

Cool, I was about to start working on a draft PR for this

It sounds like we just need to start composing hooks.

Yes, just in a way that makes sense from a naming and maintenance perspective

Copy link
Member Author

Choose a reason for hiding this comment

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

I decided to do a mix of idea 2 and 3 in #1642 now.

I did not rename useWallets but simply replaced useWalletPayment with a function that wraps useWallets (instead of useWallet as before). However, it does not return an array but it returns a single payment function that includes the wallet loop.

Therefore, I am going to close this PR since I no longer need changes to useWallets for sender fallbacks.

@ekzyis ekzyis force-pushed the useWallets-logger-sendPayment branch from 8b8cb69 to 0ffa380 Compare November 23, 2024 23:18
This makes sure that we wait for the pending poll to finish before we poll again. This prevents running multiple polls at the same time on slow connections.

I noticed we don't need to queue a new poll ourselves since a poll updates effect dependencies so we will cleanup and run the effect again anyway.
@ekzyis ekzyis force-pushed the useWallets-logger-sendPayment branch from 0ffa380 to cf152d1 Compare November 23, 2024 23:23
@ekzyis ekzyis added the wallets label Nov 24, 2024
@ekzyis ekzyis closed this Nov 25, 2024
@ekzyis ekzyis deleted the useWallets-logger-sendPayment branch November 25, 2024 03:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants