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

feat: alex swaps integration #4349

Merged
merged 9 commits into from
Oct 25, 2023
Merged

feat: alex swaps integration #4349

merged 9 commits into from
Oct 25, 2023

Conversation

fbwoolf
Copy link
Contributor

@fbwoolf fbwoolf commented Oct 12, 2023

Try out this version of Leather — download extension builds.

New PR for alex swap integration with all qa and design changes after the first version was tested here: #4205

This PR includes broadcasting the swap if we detect a tx is already pending and alex-sdk would not sponsor the swap tx.

Screen Shot 2023-10-12 at 1 39 56 PM Screen Shot 2023-10-12 at 9 00 53 AM

Submitted swap goes directly to activity tab to see pending tx...

Screen Shot 2023-10-12 at 1 04 59 PM

@kyranjamie
Copy link
Collaborator

kyranjamie commented Oct 13, 2023

The clickable area to enter the input is the red box below but, as a user, I expect anywhere within the grey box (bar the overlayed interactive element) to focus the input.

Suggest either of two solutions for this:

  1. Use relative & absolute positioning to expand the input to the entire size of its container. Padding can be used to prevent text underlaying the other elements.
  2. Make the outer box a label and target the input element by id with htmlFor
image

(Also, shouldn't there be a hover state for the input?)

Copy link
Collaborator

@kyranjamie kyranjamie left a comment

Choose a reason for hiding this comment

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

This is coming together well @fbwoolf, great work.

Fairly thorough review but think it's important we get this right, as this is hopefully the base form which we'll add others.

src/app/pages/swap/components/swap-amount-field.tsx Outdated Show resolved Hide resolved
src/app/pages/swap/components/selected-asset-field.tsx Outdated Show resolved Hide resolved
src/app/pages/swap/components/selected-asset-field.tsx Outdated Show resolved Hide resolved
src/app/pages/swap/hooks/use-alex-swap.tsx Outdated Show resolved Hide resolved
src/app/pages/swap/hooks/use-fiat-price.tsx Outdated Show resolved Hide resolved
src/app/pages/swap/swap-container.tsx Outdated Show resolved Hide resolved
src/app/pages/swap/swap-container.tsx Outdated Show resolved Hide resolved
src/app/pages/swap/swap.tsx Outdated Show resolved Hide resolved
@kyranjamie
Copy link
Collaborator

kyranjamie commented Oct 13, 2023

Some other considerations:

Ledger
These are Stacks transaction-based, right? So nothing stops us supporting Ledger. If not for first release, we should disable it. Though all the code for signing transactions is there, and it's reusable, so don't think it should be a big lift. Happy to run through what's needed for this.

Market data updates
When a user is on the form, fills in a value, market data changes, how does this propagate through the state? Polling only? If so, how fast? Is there a websocket we can use? When market data updates, how do we inform the user that values have changed? cc/ @fabric-8 @mica000

Automated Tests
We're handling money so we should proactively think about what could go wrong, and test those things

/swap/btc/usda
The selected assets should be reflected in the URL. Think we'll this included for:

  • Analytics' sake
  • Adding the functionality to restore where the user is when closing/opening popup

Loading swap data
We need loading indicators to show that we're waiting for quotes. Further, the way we handle promise updates needs some work. Consider video below where, the requests are slow (because they're contract calls) and I'm on a slow connection both because I've enabled it in devtools and I actually am using 4g on a bus 🚌. I make several updates, and in sequence, the requests resolve updating one by one. This is unexpected because by the time I've entered the last 0.3 stacks, I don't care about the result of the 0.1 from two edits ago. As soon as a user enters a new value, the HTTP request and logic to update the form should be cancelled, such that the latest value only is used. It's entirely possible that when I enter 0.1, 0.2, 0.3 the stale 0.1 request finishes last, thus updating the form with wrong data. These are general complexities of async programming, but things we ought to fix as otherwise it will break.

2023-10-13-000014.mp4

Happy to help figure out ways to implement this, these are similar problems I've faced working on an exchange in the past. The trading form we had was by far the largest, most complex part of the codebase, and this is what we're doing here.

@fbwoolf
Copy link
Contributor Author

fbwoolf commented Oct 13, 2023

Some other considerations:

Ledger These are Stacks transaction-based, right? So nothing stops us supporting Ledger. If not for first release, we should disable it. Though all the code for signing transactions is there, and it's reusable, so don't think it should be a big lift. Happy to run through what's needed for this.

I think we can disable for Ledger and do as an enhancement issue? cc @markmhendrickson

Market data updates When a user is on the form, fills in a value, market data changes, how does this propagate through the state? Polling only? If so, how fast? Is there a websocket we can use? When market data updates, how do we inform the user that values have changed? cc/ @fabric-8 @mica000

I think this should be a wallet enhancement issue bc the market data implementation for the send form needs to also consider this, and it needs to be looked at again? cc @markmhendrickson I wasn't able to reuse it here, and currently no sip10 tokens are even using fiat conversions in the send form.

Automated Tests We're handling money so we should proactively think about what could go wrong, and test those things

Yep, will try to add integration tests here.

/swap/btc/usda Think we'll this included for:

  • Analytics' sake
  • Adding the functionality to restore where the user is when closing/opening popup

Not understanding what you mean here?

Loading swap data We need loading indicators to show that we're waiting for quotes. Further, the way we handle promise updates needs some work. Consider video below where, the requests are slow (because they're contract calls) and I'm on a slow connection both because I've enabled it in devtools and I actually am using 4g on a bus 🚌. I make several updates, and in sequence, the requests resolve updating one by one. This is unexpected because by the time I've entered the last 0.3 stacks, I don't care about the result of the 0.1 from two edits ago. As soon as a user enters a new value, the HTTP request and logic to update the form should be cancelled, such that the latest value only is used. It's entirely possible that when I enter 0.1, 0.2, 0.3 the stale 0.1 request finishes last, thus updating the form with wrong data. These are general complexities of async programming, but things we ought to fix as otherwise it will break.

Tbh, I don't see a real problem in the video? I would have to better understand how the design team would want to handle this, right? I think this could be an enhancement issue? cc @markmhendrickson

@fbwoolf
Copy link
Contributor Author

fbwoolf commented Oct 13, 2023

Thx @alter-eggo for just making change commits here. I see now the best way to handle those changes. 👍

@kyranjamie
Copy link
Collaborator

Not understanding what you mean here?

That the selected assets should be reflected in the routes, such as with the example provided.

Tbh, I don't see a real problem in the video? I would have to better understand how the design team would want to handle this, right? I think this could be an enhancement issue? cc @markmhendrickson

Sorry maybe I didn't explain well. But notice how when I type the 3 values changes, you can see the updates coming in sequentially. This highlights a race condition, that represents a serious bug.

Let's say of those 3 requests to check the price:

  • 0.1 takes 3 seconds
  • 0.2 takes 2 seconds
  • 0.3 takes 1 second

What happens in the form here? I'm pretty sure that despite 0.3 being the last value typed, because the 0.1 value resolves last, we update the field with an incorrect value. This is a common async mistake. We need to debounce it in such a way that only the most recently response is used, and old values are discarded. In your testing, you'll likely never encounter this, as the requests generally do take the same amount of time so will be returned in correct order, but we can't make that assumption.

To test this, you can create a fake HTTP call that returns values at different times.

Unless I'm mistaken this is race condition bug serious enough such that we shouldn't merge this PR until fixed.

@mica000
Copy link

mica000 commented Oct 13, 2023

@fbwoolf thanks for working on this again. Looking nice

In relation to this component, here is what could improve

BUTTON TOKEN

Current
Screenshot 2023-10-13 at 18 31 55

Designs
Link to Figma component
Screenshot 2023-10-13 at 18 36 04
Screenshot 2023-10-13 at 18 32 08

  • Padding 8px all around instead on 8,8,8,16;
  • Token size 32px instead of 24px;
  • Copy: You'll pay / You'll receive? cc @kyranjamie @markmhendrickson
  • Hover color: brown 2 (Link to color scheme - but maybe the color scheme used is not updated yet?)

@mica000
Copy link

mica000 commented Oct 13, 2023

Button validation

Wondering if we could disable the CTA instead of showing it enable permanently?
So it would only be active when the swap is valid.

Screenshot 2023-10-13 at 18 30 18

@fbwoolf
Copy link
Contributor Author

fbwoolf commented Oct 13, 2023

I think I should add a maxLength to the input here too, like we do in the send form, bc UI issues with long values.

@fabric-8
Copy link
Contributor

fabric-8 commented Oct 13, 2023

On dark mode, the color of the actual input is off. Also not quite sure why "Select asset" is line breaking... maybe s.th. on my end? Otherwise things are looking good!
CleanShot 2023-10-13 at 21 50 25@2x

@fbwoolf
Copy link
Contributor Author

fbwoolf commented Oct 14, 2023

On dark mode, the color of the actual input is off. Also not quite sure why "Select asset" is line breaking... maybe s.th. on my end? Otherwise things are looking good!

Thx for letting me know about the dark mode bug. I will fix it. I saw the Select asset button off in Kyran's video too so maybe I pushed up a change that broke that ...I don't see it locally so I must have fixed it. I'll double check though, thx!

@mica000
Copy link

mica000 commented Oct 16, 2023

Sn add to the comments above about the component "Token button"

  • Just noticed the chevron seems to get small depending on the size of the token name?
  • Line breaking on the text "select token" should be removed
Screenshot 2023-10-16 at 13 12 36 Screenshot 2023-10-16 at 13 12 31 Screenshot 2023-10-16 at 13 17 50

@markmhendrickson markmhendrickson linked an issue Oct 16, 2023 that may be closed by this pull request
@314159265359879
Copy link
Contributor

This "info/tooltip" looks like it is appropriate on the ALEX dapp where users can provide liquidity through the "Pool" option in the navigation bar but that is not the case in the wallet.

Change info to something like this instead?:
To receive a share of these fees, become a Liquidity Provider on app.alexlab.co.
image

@314159265359879
Copy link
Contributor

I think some routed swaps are not displayed properly. Going to Slime or Banana for example. The contract call is such that the swap is still routed from STX to ALEX to SLIME so it does get executed properly.

image

Expected is this:
image

@fbwoolf
Copy link
Contributor Author

fbwoolf commented Oct 17, 2023

Change info to something like this instead?:

cc @mica000 ?

@fbwoolf
Copy link
Contributor Author

fbwoolf commented Oct 17, 2023

I think some routed swaps are not displayed properly. Going to Slime or Banana for example. The contract call is such that the swap is still routed from STX to ALEX to SLIME so it does get executed properly.

I think I broke this, thx, I will fix. 👍

@mica000
Copy link

mica000 commented Oct 17, 2023

Change info to something like this instead?:

cc @mica000 ?

Updating my comment about Tooltips:

Transaction fee
"Swap transactions are sponsored by default. However, this sponsorship may not apply when you have pending swap transactions. In such cases, if you choose to proceed, the associated costs will be deducted from your balance."

Design: https://www.figma.com/file/nY5UTVUoJdLQ30sk7YGQ3Y/%F0%9F%94%81-Swap?type=design&node-id=1313-18932&mode=design&t=OsV1EXOjRFAtujev-4

Liquidity provider:
"To receive a share of these fees, become a Liquidity Provider on app.alexlab.co"

cc @314159265359879 @fbwoolf

@314159265359879
Copy link
Contributor

With the exception of USDA and STX (6), all the tokens on ALEX have 8 decimals. Want to limit the amount of decimals shown here for "minimum received", to improve readability?
image

@mica000
Copy link

mica000 commented Oct 18, 2023

When trying to do a second transaction it's giving me a nonce error:
SCR-20231018-jdhf

@mica000
Copy link

mica000 commented Oct 18, 2023

In the extension, seems like when the number is too long the alignment breaks to the left, possible to align to the right?
Screenshot 2023-10-18 at 09 51 41

@fbwoolf
Copy link
Contributor Author

fbwoolf commented Oct 18, 2023

When trying to do a second transaction it's giving me a nonce error:

This might be a random nonce issue bc using nextNonce code that the entire wallet uses (in send form too). I will check it, but not sure this is related to swaps ...unless I broke the NonceSetter we use refactoring to use useAsync ...will check it, thx.

@fbwoolf
Copy link
Contributor Author

fbwoolf commented Oct 18, 2023

In the extension, seems like when the number is too long the alignment breaks to the left, possible to align to the right?

Looks like it was pointed out from @314159265359879 that I missed using the token decimals here, which should help this, but will check alignment too.

@fbwoolf
Copy link
Contributor Author

fbwoolf commented Oct 18, 2023

Transaction fee "Swap transactions are sponsored by default. However, this sponsorship may not apply when you have pending swap transactions. In such cases, if you choose to proceed, the associated costs will be deducted from your balance."

For the record here, the language will be ...when you have pending transactions. It can be any pending Stacks transaction.

@fbwoolf
Copy link
Contributor Author

fbwoolf commented Oct 18, 2023

In the extension, seems like when the number is too long the alignment breaks to the left, possible to align to the right?

Should the label be changed here, isn't the past-tense Minimum Recevied a bit odd if the tx is just submitted and not confirmed yet? Also, there label should only have the first word capitalized?

Copy link
Collaborator

@kyranjamie kyranjamie left a comment

Choose a reason for hiding this comment

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

This an improvement as indeed this removes the race condition, and the loader communicates something's happening. I feel users may expect to see how much they're going to get before blurring though, this is how it works on Rainbow.

Another solution that I think might be worth having a look at is debouncing the input and cancelling the previous action when there's a new input. This can come later if urgent to release.

Lastly, curious why we're not using yup for form validation as elsewhere? There's lots of manual error setting/resetting everywhere setError({}) etc

bg: 'brown.6',
},
bg: 'brown.6',
color: 'white',
Copy link
Collaborator

Choose a reason for hiding this comment

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

should use a token

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Confused a bit by our setup for colors, what is the right token to use here? I was following the other button receipe colors using brown.6, but I don't see what white would be?

@fbwoolf
Copy link
Contributor Author

fbwoolf commented Oct 24, 2023

This an improvement as indeed this removes the race condition, and the loader communicates something's happening. I feel users may expect to see how much they're going to get before blurring though, this is how it works on Rainbow.

Ok, ShapeShift does it onBlur in their swaps so felt it was a good path.

Another solution that I think might be worth having a look at is debouncing the input and cancelling the previous action when there's a new input. This can come later if urgent to release.

Happy to try this or follow up with it after first release. We can all talk abt it in mtg today.

Lastly, curious why we're not using yup for form validation as elsewhere? There's lots of manual error setting/resetting everywhere setError({}) etc

Yup is being used here. I validate on mount to disable the button, which was requested in qa review. Then I have to handle some things with errors later, but is that wrong? Those methods exist for a reason from yup?

@kyranjamie
Copy link
Collaborator

Yup is being used here. I validate on mount to disable the button, which was requested in qa review. Then I have to handle some things with errors later, but is that wrong? Those methods exist for a reason from yup?

Could be wrong but, afaik, you can either do validation with formik via their own methods, e.g. setErrors, or by passing a validation schema. If we're doing both, aren't we mixing two methods of validation?

@fbwoolf
Copy link
Contributor Author

fbwoolf commented Oct 24, 2023

Could be wrong but, afaik, you can either do validation with formik via their own methods, e.g. setErrors, or by passing a validation schema. If we're doing both, aren't we mixing two methods of validation?

Yeah, not sure here about if only one method is supposed to be used, is that in the docs somewhere? I can def try to rework it so only using one method, but will just take some time.

@fbwoolf fbwoolf force-pushed the feat/alex-swaps branch 2 times, most recently from f495763 to e3f8ee2 Compare October 24, 2023 17:06
@fbwoolf
Copy link
Contributor Author

fbwoolf commented Oct 24, 2023

@kyranjamie any thoughts on the failing tests here? I rebased on dev and now can't get past these errors ...failing on chrome being undefined? I've cleaned my local > reinstalled yarn.lock and node_modules ...made sure I'm using node 18.18.0. 🤔

@fbwoolf
Copy link
Contributor Author

fbwoolf commented Oct 24, 2023

Could be wrong but, afaik, you can either do validation with formik via their own methods, e.g. setErrors, or by passing a validation schema. If we're doing both, aren't we mixing two methods of validation?

Looked into this today, I am only using setFieldError when we have to use setFieldValue when setting the exchange rate value of the swap. I have to do this bc we validate the form onMount which creates a required error for the amount to field. I have to clear it manually when I set the field value manually. I don't see in the docs that using a validation schema for onMount and onSubmit along with manual validation is bad, but maybe I am missing. I can write manual validation for the onMount and onSubmit, but not sure why I would do this. I also call validateForm() manually when the toggle button is used, but I can remove that and just let the validation happen when the user submits the form again.

@fbwoolf fbwoolf force-pushed the feat/alex-swaps branch 2 times, most recently from 5f6c51f to bbfea9c Compare October 24, 2023 21:11
@fbwoolf fbwoolf force-pushed the feat/alex-swaps branch 4 times, most recently from 954e257 to 6c6eca4 Compare October 25, 2023 01:03
@fbwoolf fbwoolf added this pull request to the merge queue Oct 25, 2023
Merged via the queue into dev with commit d9bd157 Oct 25, 2023
26 checks passed
@fbwoolf fbwoolf deleted the feat/alex-swaps branch October 25, 2023 15:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Integrate ALEX swaps
8 participants