-
Notifications
You must be signed in to change notification settings - Fork 32
Nimiq Wallet Demo #263
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
base: master
Are you sure you want to change the base?
Nimiq Wallet Demo #263
Conversation
…ions with error handling
Hey Maxi, thanks for putting this together, this will be such a helfpul resource! |
Buy Fake NIMCompletely agree with you, an interface where users can enter a number and that amount gets added to the balance is perfect. This is not too far from how the original interface for buying via OASIS looked like: I think it would be cool to bring it as close as possible to this, as even though users right now will have to go through moonpay et al, this would be the most native way to buy within the wallet. Can we mock a bank and identicon (we do have a generic bank icon too)? Can we show the fiat equivalent or would this be too much work? Here's the link to the Figma designs Commented by Maxi: ✅ Done Instead of the DEMO banner in the modal, I'd add a note to the whole interface (e.g. where we have the "POS Testnet" note), additionally if we think that's not enough, maybe a little note below the button saying that this is not real money and just for demo purposes. Commented by Maxi: ✅ Done Also in the TX list, would be cool to have a [fake bank icon instead of the identicon].(https://www.figma.com/design/D07VHQmmYSaOipkiivRjwv/Wallet-Fiat-Swaps?node-id=756-0&t=Ruacw6pwydVVUxsh-11) Commented by Maxi: ✅ Done |
Thanks @julianbauer. You can also add yourself as reviewer and add a review with
Really nice solution. I will update the designs and propose a wording that we like :).
Yep I think we can do that. For that I believe we need to fake the swap as if the user has used supersimpleswap. I didn't want to add a sss swap since the service is offline for more than a year. Should we really add it? I believe this swap is only in EUR, so a person from other continent don't care about this feature. |
As we're faking it all anyway, could we just... fake it? Like, we probably have a fixed address for this transaction, couldn't we just replace the identicon with the bank icon? Or am I missing sth? Commented by Maxi: ✅ Done |
I'm against adding a EUR swap, as we are not currently offering that and don't know if we'll ever do again. |
Stake NIMLooks good! Probably obvious but 2 things:
|
I'm with you, I wouldn't call it "the EUR swap" or link it to any of the services currently unavailable. It does provide an interface though that I think is nicer and closer to reality than just a single input, and by itself is quite neutral. Considering we have these anyway, why not use them? Commented by Maxi: ✅ Done! |
Swap NIM
|
Great ideas, agreed! Fallback modalFor the fallback modal, we'll come up with a custom design for this. Essentially we want to say "Hey this functionality doesn't exist because this is a demo, but if you're hooked, create a wallet and see the real thing" Commented by Maxi: Fake addressesCould we just use special characters in the middle of the addresses? Like NQ26 2Y2M XXXX XXXX XXXX XXXX XXXX MDIF 5SKD? That should generate identicons too, right? On top of that we should definitely deactivate all copy functionality (like clicking the address in Receive modal), and add a note to users to not send funds to these addresses because they don't exist Commented by Maxi: |
Agreed, but outside of the scope of this PR. The UI will be updated automatically when new designs get implemented.
I will check how to do it, but I believe I might need to change some code in the application side, which is something I am trying to minimize. I will see how I can do it :)
No problem
Ok, I think I missed a step in the faking process.
I will update the buy flow with check mark then.
I will see the easiest way to do it without any impact.
Ok, waiting for it.
It will not generate identicons as I believe the code will say is a invalid address. but I can look for a work-around. Thanks for you valuable feedback. I have updated the TODOs section in this PR to track progress |
Btw I'm basing my assumption on this demo here, where any text creates an identicon. Not sure how applicable this is of course: https://github.com/nimiq/identicons?tab=readme-ov-file But then, as another workaround, you could use a real address for the identicon, but only show the masked version of it. There's no way to guess the address from the identicon so we should be safe! |
Under the hood we are using But I think is going to change just the text content that we render and leave the identicon itself with a correct address as you mention |
Working on your feedback now. I just realized that we didn't think about the receive modal. I am thinking of disabling the receive modal completely and always redirecting to the fallback modal. There is no need to show the receive modal at all in the demo. Let me know if this works for you. Thanks a lot! |
Ach, I think it's nice seeing how it looks like. If we mask the address properly like in your screenshot, I think there's value in showing it, just for context. Commented by Maxi: ✅ Done |
The issue now is the QR codes and request link. How should we handle those? |
I'd suggest to draw the line there: These can be left out :) – show the fallback modal when clicking on them |
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.
minor adjustments needed
8614787
to
ef9e296
Compare
Demo Mode for the Nimiq Wallet
This PR provides a complete demo environment for the Nimiq Wallet, allowing users to try out wallet features without connecting to real blockchain networks.
How to activate it
Run
yarn serve:demo
oryarn build:demo
.When active, demo mode:
This will be useful for the coming new nimiq.com/wallet page. As soon this feature goes live, soon after the new page will be updated.
The user sees and interacts with the wallet as any other user would with a real account. The difference is that the state, information and logic have been faked. Together with some visual cues, we invite the user to use and experiment with the Wallet, making sure that we set boundaries between what is real and what is not.
A picture is worth a thousand words, and a video is made of thousand1 pictures, so here are some videos:
Buy Fake NIM
A new UI has been developed for the modal
Screen.Recording.2025-03-12.090426.mp4
Stake Fake NIM
Screen.Recording.2025-03-12.093021.mp4
Swap NIM/BTC
Screen.Recording.2025-03-12.090720.mp4
TX details
If you want to see the transactions details being used:
defineNimFakeTransactions
,defineBtcFakeTransactions
,defineUsdcFakeTransactions
ordefineUsdtFakeTransactions
Try it yourself. Live preview.
demo
branch.Technical details.
Development
git fetch origin git checkout demo yarn install yarn serve # open http://localhost:8081?demo
Tip
One good thing about this new feature is that we no longer have to run Keyguard and the Hub in parallel. Very useful if you are working on UI stuff.
Enabling the Demo.
Make sure to enable
demo.enabled
:New build
When running
yarn build:demo
oryarn serve
with the demo initialized, we will use ``i18n strings are extracted
BitcoinJS is built if not already present
The build is triggered with the build=demo environment variable
This makes Vue CLI use src/main-demo.ts as the entry point instead of src/main.ts
The config file src/config/config.demo.ts will be used
A special release tag is created in the format demo-YYYY-MM-DD to identify the demo build
All assets are compiled and optimized for production use
Enabling USDC/USDT on Polygon.
Make sure to enable the fastspot
How this was implemented?
Visual summary
I've tried to touch as little code from the current application as possible, as we don't want to introduce any problems for current users. All demo related code can be found in
lib/Demo.ts
. I decided not to create multiple files on purpose, even though the code is a bit spaghetti in my opinion.main.ts
We don't want to write anything to the user's storage, so when the application is initialised, the first thing it does is check whether the
?demo
parameter exists or not.If we are in the demo environment the stores will not be persistent.
We also "inject" the
?demo
parameter after each route change.Hub API
We don't want to launch the Hub API when the demo is active. So a new "mock" implementation of the Hub API has been introduced:
This demo, will block any attempt to open the hub popup and instead handle the opening of the new "DemoModalFallback" which will let the user know that the demo functionality is limited and they have reached the end of the demo.
Sometimes the HubAPI will not display this modal and will instead fake the operation. For example, if you are exchanging two currencies, the Hub API will create a fake exchange and you will see the whole process.
You can see the
DemoHubApi
in the./lib/Demo.ts
and the "Faked Flows" section in this PR.Fake accounts & transactions
To add some realism, we insert fake transactions in NIM, BTC, USDC and USDT. The transactions in NIM have customised messages using cultural references from around the world. Fun fact: the NIM amount is
140418
, which is a date:14th of april, 2018
.We are prioritizing realism, so instead of using a
Math.random
for the values of each transaction we do use a ratio of the total amount that the user has now. This allows us to confidently know that the balance shown in the overview matches the transaction history.Faked flows
One of the reasons of the Nimiq Wallet Demo is to let the user play without an account. Therefore the most notorious and important flows have been faked.
These are the faked flows:
replaceBuyNimFlow
functionreplaceStakingFlow
functionSwapModal
logic, but we intercept the fetch requests to the Fastspot API like the/limits
for the swaps. For each of the key points in the dataflow, we return a specific set of values. SeeinterceptFetchRequest
.The rest of data flows are
The next flows from the Wallet are out-of-scope:
Adjust stakeUnstakeSell cryptoSwaps involving USDC/USDTBuy BTC & USDCCommunication with the host
Since this feature will be used as an
iframe
, we would like let the host and the app talk to each other. Therefore, we have the functionattachIframeListeners
.Basically, the user has the option to click on "buy", "stake" or "swap" on the website. The selector will have one of the options highlighted when the user is in that flow.
Therefore, this communication needs to be two-way, meaning that if the user changes the flow from the application, the application needs to communicate this to the host, or if the user changes the flow from the selector, the host needs a request to initialise to that flow.
This has yet to be tested
Custom CSS + Visual cues
When the demo is enabled we add also some visual cues to the user to let them know where to click. This cues are added from
Demo.ts@setupVisualCues
function.We also inject some CSS to make some minor adjustments.
Comment about Swaps
The demo only allows you to swap between NIM and BTC. Adding more cryptos add too much complexity and it is outside of the scope. We just need a minimal swap demo for users to enjoy.
Therefore the following things have been removed from the UI:
The removal of this items is dynamically and happens in
Demo.ts
.Fallback Modal design
Using DOM observation
In order to minimize writing code in the core app logic, we have decided to use MutationObserver to watch for UI changes:
Demo Mode notice
In the top left a new banner has been included to warn about the demo mode
Obfuscate addresses
In order to avoid loss of funds, all the NIM addresses have been replaced with
XXXX
as shown in the picture. The content that we write to the clipboard will beThis is a demo address - not for actual use
.UX improvements
Translations
Should we translate the transactions messages and labels?
QA
The demo does not require any Hub nor Keyguard, making it easy to be used this mode for QA tasks. Like selecting address, interacting with the swap modal, navigate the address...
TODO
Fill NIM first
When we do a swap NIM -> BTC, I am not sure how modify the code in
listenForSwapChanges
in order to set the value so the animation first fills the NIM and then the BTC.Footnotes
We both know that this is not exactly true, but if I try to be correct, the sentence loses its wit. ↩