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: move fidelity bonds to earn screen #361

Merged
13 commits merged into from
Jul 6, 2022
Merged

feat: move fidelity bonds to earn screen #361

13 commits merged into from
Jul 6, 2022

Conversation

ghost
Copy link

@ghost ghost commented Jul 4, 2022

Resolves #339.

Moves fidelity bonds to the earn screen, updates the UI, and adds UTXO selection. Consider this the base version of the
feature that we can build upon in separate PRs.

👇 A fair chunk of the new lines of code are tests and CSS, don't worry too much about that number. 😄
Screenshot 2022-07-05 at 15 05 35

📸 How does it look?

Screen.Recording.2022-07-05.at.15.13.29.mov

💡 Possible Improvements

I'll track these points as separate issues if you guys agree on them.

Things we MUST do before releasing

  • Redo all of the wording and move it to the translation.json file. At the moment everything is either dummy text or copied from Figma or elsewhere without much thought.

Things we SHOULD consider doing before releasing if we have the time

  • Reload the earn page after creating a fidelity bond.
  • De-emphasize the UI for creating a second fidelity bond if another one already exists. It's not really useful to do so.
  • Use TypeScript in the main CreateFidelityBond UI component and redo some of the logic to be more concise and less all-over-the-place.
  • Offer to unfreeze the UTXOs that were frozen during the flow.
  • Warn the user when selecting non cj-out UTXOS (e.g. by making the final button red similarly to how we do it when sending a "normal" transaction on the Send screen.)

Things we MIGHT consider as improvements for a future releases

  • Offer to make an intermediate CJ transaction before funding the fidelity bond (see community call #18)
  • Paginated (or otherwise more space efficient) UTXO selection.

Let me know what else you would like to see.

@ghost ghost added enhancement New feature or request UI/UX Issue related to cosmetics, design, or user experience labels Jul 4, 2022
@ghost ghost requested a review from theborakompanioni July 4, 2022 13:48
@ghost ghost self-assigned this Jul 4, 2022
@ghost ghost force-pushed the fb-earn-screen branch from b9a1ccb to 540dfaa Compare July 4, 2022 13:51
@theborakompanioni
Copy link
Collaborator

theborakompanioni commented Jul 4, 2022

Tested it a bit and must say: It rocks 🪨 🪨 🪨 🚀

Aside from the things you are already aware of or you have even mentioned above: What follows are random thoughts, in no particular order, I am sure you also had during development. Some of them have been also brought up in the previous Community Call. However, it is always beneficial to take note of them:

  • UTXO list can potentially be quite long, let's consider how UX can be improved

    • e.g. Should the list be displayed in a modal? Should it be paginated?
      I guess every option has it's own benefits and drawbacks, it just has to be agreed upon.
  • Should utxos be sorted in some way?

  • Should we add a warning or a hint to only select "cj-out" utxos, or encourage users
    to run the scheduler before creating a FB?

  • What are your thoughts on unfreezing previously frozen during the FB setup?
    Can this be done in a non-confusing way without destroying UX?

  • Have you thought about externalizing coin control completely in the first version?
    i.e. Coin control must be performed before the FB setup is started
    Would this simplify the form and make it easier to grasp?
    (e.g. can be linked from the FB form but user realize it is a separate functionality)

  • Creating an additional Fidelity Bond is very prominent, let's not forget to inform the user what this means
    (e.g. only one FB is "active"; it does not make sense to create another FB with lower date/smaller amount)

  • By glancing over the code:

    • Noticed async/await inconsistencies. Can be tackled later on.
    • Error state handling: What would really happen if some steps fail?
      • e.g.: freezeUtxos or directSweepToFidelityBond?

Small issues:

  • dark mode artifacts
  • loading state inconsistencies

Other thoughts:

  • The utxos selector items "look like" radio buttons, which implies that only one is selectable.
    I think it is neglectible, but if UTXO selection is kept, are checkboxes more appropriate?

I guess the most important question is whether to keep coin control in the FB setup or complete externalize it.

Great job by the way. Definitely better than anything I could come up with. Really nice 🧡

@ghost
Copy link
Author

ghost commented Jul 5, 2022

Thanks for the feedback @theborakompanioni, I've added a couple more things and updated the description accordingly. I'm marking this as ready for review now. It's still not perfect but I feel like anything else can be done in distinct improvement PRs. Let me know what you think! 🙏

@ghost ghost marked this pull request as ready for review July 5, 2022 13:02
@ghost ghost requested a review from dergigi July 5, 2022 13:07
Copy link
Contributor

@dergigi dergigi left a comment

Choose a reason for hiding this comment

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

Great work @dnlggr! 👏

Code looks good to me in general, see NITs inline; only the one TODO is something that should be removed I believe.

I did my best to test this quite thoroughly, and out of the 6-or-so back-to-back test runs I think I managed to break it once. I created a fidelity bond and made some transactions and did some freeze/unfreeze operations, and suddenly the fidelity bond was gone. Not sure what happened, will try to reproduce it again tomorrow. I also managed to reproduce the Gateway timeout error around the same time, so maybe something just broke completely (something that is unrelated to this PR).

I'll give this a tACK now anyway, since we are running with scissors (and I wasn't able to reproduce whatever I did, and it's absolutely possible that nothing is wrong and I'm just stupid in the first place). So: LGTM ✅

I agree on the improvements listed, and here are some additional things that could be tracked for follow-up PRs:

  • Add a back button for every step (currently there is no way to go back a step)
  • Improve confusing iconography ("frozen" uses a lock; on the next step, "UTXOs that will be locked up" shows a lock again; same symbol for two things that are the opposite --> very confusing!)

UX wise the biggest improvements would be a button to batch-unfreeze all frozen UTXOs that were just frozen (or all UTXOs in the jar that were selected). Pre-selecting the largest cj-out or something like that would be cool too, that way you can just go "next next next". The batch-unfreeze is almost a must for 0.1.0 I'd say.

In any case, great job, this is already amazing for a first iteration! 💪 🚀

As mentioned inline, I will take care of the final copy in a separate PR.

const { mixdepth } = utxo
res[mixdepth] = res[mixdepth] || []

// todo: remove
Copy link
Contributor

Choose a reason for hiding this comment

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

Remove before merge? (I assume the below was a hack for testing cj-outs on regtest?)

Edit: I guess you left it in on purpose so we can test it. In that case: thanks! 😅 🙏

Copy link
Author

Choose a reason for hiding this comment

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

Yep definitely needs to go before merging. Removed now. ✅

<ConfirmModal
isShown={showConfirmInputsModal}
title={'Are you sure you want to lock your funds?'}
body={`Be aware that your funds can only be moved again when the fidelity bond expires on ${new Date(
Copy link
Contributor

Choose a reason for hiding this comment

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

Note to self: would be cool if we also show total duration in days/weeks/months/years. Here and also in the summary view.

src/components/fb/FidelityBondSteps.tsx Outdated Show resolved Hide resolved
src/components/fb/FidelityBondSteps.tsx Outdated Show resolved Hide resolved
<div className="d-flex flex-column gap-4">
<div className={styles.stepDescription}>
Fidelity bonds are a feature of JoinMarket which improves the resistance to sybil attacks, and therefore
improves the privacy of the system. This should be a better and easier to understand description and let the
Copy link
Contributor

Choose a reason for hiding this comment

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

😆 --- I will take care of the final copy, don't worry 😅

@theborakompanioni
Copy link
Collaborator

theborakompanioni commented Jul 6, 2022

No major flaws or issues detected.

Some minor stuff:

  • Balance of ExistingFidelityBond is always displayed despite value of settings.showBalance

  • After an error, the alert remains visible, even when a retry is successful.

  • Utxo with expired lock is displayed as "locked", but can be selected. This feels odd and might be a bit confusing - funds are not locked anymore. After freezing (when not selected for the next fb) it still says "locked", now however, "frozen" seems to be more appropriate.

  • async/await "issues": Some functions are marked as async with a single await statement that continues to use promise-style syntax. These functions are in turn called by synchronous functions (without subscribing to the promise). This seems a bit awkward. If this pattern is seen, one can either remove async/await or remove the promise-style syntax. "At least" subscribe to the returned promise.

Most of the following is related to UI/UX - hence, my opinion should not be given too much weight.
Some of them seem to be "easy wins". All this can be done in follow-up PRs.

  • Should an expired fidelity bond be styled differently?
    Currently, if multiple FBs exist, all look the same, expired and non-expired ones.

  • If multiple FBs exist: What about sorting them by expiry date?

  • Utxos with a non-expired lock are displayed even when they can never take part in the transaction.
    What do you think about not showing them in the first place?

  • Same is for frozen utxos. They could take part in the tx, but they are not selectable in the UI.
    Here too: Keep showing them or should they be hidden?

    Edit: There might be reasons to display them. What are your pros/cons regarding this?
    I see a benefit with always showing all utxos, because it is quite a simple strategy, without surprises.
    In this case, however, placing non-expired locked or frozen utxos at the bottom of the list would be great.

NITs (just for reference):

  • Checked/Unchecked checkboxes have different widths for utxos with expired lock

  • Disable Jar with no availableBalance? e.g. A jar with all utxos frozen or locked is still selectable.

  • Freeze step incl. phrase "The following UTXOs will not be used for the fidelity bond." shown, even if no utxo is about to be frozen.
    (Either all utxo have been selected, or all utxos left are already frozen)

  • After a FB is created, and the "close" button is pressed, the accordion body is empty.

<div>locked</div>
</div>
)}
{!isLoading && !utxo.frozen && utxo.label === 'cj-out' && (
Copy link
Collaborator

@theborakompanioni theborakompanioni Jul 6, 2022

Choose a reason for hiding this comment

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

Just noticed that the classification (new, deposit, cj-out, etc.) are not provided in the data from /utxo, but only in /display, where they are not on "utxo", but on "address" level..

Nonetheless, I think displaying the label here (even when it cannot be set by Jam yet), is a good idea.

This is an object in entries of the display response:

{
	"0": {
		"hd_path": "m/84'/1'/1'/1/0",
		"address": "bcrt1qeme6gzjlj5s95jfe8hwauagy8y45teh4rej8jw",
		"status": "cj-out",
		"label": "",
		"extradata": "",
		"amount": "149.99994620",
		"available_balance": "149.99994620"
	}
}

Compare with the utxo data structure (no status here):

{
	"0": {
		"address": "bcrt1qeme6gzjlj5s95jfe8hwauagy8y45teh4rej8jw",
		"path": "m/84'/1'/1'/1/0",
		"label": "",
		"value": 14999994620,
		"tries": 1,
		"tries_remaining": 2,
		"external": false,
		"mixdepth": 1,
		"confirmations": 7,
		"frozen": false,
		"utxo": "9dbd6db083b3fb23c936bd16dbc52efa64330a3145d4c8c9492136a00c8e4c80:1"
	}
}

Copy link
Author

@ghost ghost Jul 6, 2022

Choose a reason for hiding this comment

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

If I understand correctly, the API does not return the UTXO labels in the UTXO endpoint but only for the /display wallet endpoint on an address label and we need to manually match up UTXOs and addresses to find out which UTXO has which label? 🤔

Do you know what the difference between a label and a status is?

Copy link
Collaborator

@theborakompanioni theborakompanioni Jul 6, 2022

Choose a reason for hiding this comment

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

If I understand correctly, the API does not return the UTXO labels in the UTXO endpoint but only for the /display wallet endpoint on an address label and we need to manually match up UTXOs and addresses to find out which UTXO has which label? thinking

Correct.

Do you know what the difference between a label and a status is?

A label is manually applied by the user (https://github.com/JoinMarket-Org/joinmarket-clientserver/blob/3140616d322c85e71591d8d4d46cbb4cea374002/docs/release-notes/release-notes-0.9.4.md#user-chosen-address-labelling). Whereas the status is a categorization applied by the backend (https://github.com/theborakompanioni/joinmarket-clientserver/blob/36bf36bd65f6365cb282a8abf3512e8e11df548a/jmclient/jmclient/wallet_utils.py#L493-L531).

Copy link
Author

Choose a reason for hiding this comment

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

Do you know if there is there any reason for not having the status in the UTXO? 🤔

@ghost
Copy link
Author

ghost commented Jul 6, 2022

Utxo with expired lock is displayed as "locked", but can be selected. This feels odd and might be a bit confusing - funds are not locked anymore. After freezing (when not selected for the next fb) it still says "locked", now however, "frozen" seems to be more appropriate.

We'd need a way to check if the lockdate is in the past. Do you know what timezone the lockdate returned from JM is? I'm guessing UTC but can't find any docs. 😢

@ghost
Copy link
Author

ghost commented Jul 6, 2022

async/await "issues": Some functions are marked as async with a single await statement that continues to use promise-style syntax. These functions are in turn called by synchronous functions (without subscribing to the promise). This seems a bit awkward. If this pattern is seen, one can either remove async/await or remove the promise-style syntax. "At least" subscribe to the returned promise.

You are right of course. Removed the async/await keywords. Please have another look if you can. 🙏

@theborakompanioni
Copy link
Collaborator

We'd need a way to check if the lockdate is in the past. Do you know what timezone the lockdate returned from JM is? I'm guessing UTC but can't find any docs. cry

It's a unix timestamp, so no timezone. Date.UTC (albeit in milliseconds) can be used to compare the value: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/UTC

Already present, just not well placed in BalanceSummary.ts: https://github.com/joinmarket-webui/joinmarket-webui/blob/master/src/hooks/BalanceSummary.test.tsx#L10-L36
Move it wherever you see fit!

@ghost
Copy link
Author

ghost commented Jul 6, 2022

Thanks for the detailed feedback @dergigi and @theborakompanioni! 🙏

📋 I've tracked a whole bunch of follow up issues here.

I've roughly split them up between v0.0.9 (issues that improve the current flow) and v0.1.0 (issues that are either only nice to haves or extend the current flow) although I do think that we can do an intermediate release and move some of the "not so high prio but still kinda important" issues to an intermediate v0.9.1 before we get going on the big v0.1.0.

@ghost ghost merged commit 8608329 into master Jul 6, 2022
@ghost ghost deleted the fb-earn-screen branch July 6, 2022 12:54
@ghost ghost mentioned this pull request Jul 7, 2022
This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request UI/UX Issue related to cosmetics, design, or user experience
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Move fidelity bonds to earn screen and update UI
2 participants