How to update ERC20 token amounts in React Native application quicker? - reactjs

I'm currently updating a cryptocurrency loyalty rewards application written in React Native. The app allows you to "donate" or send tokens to others.
I need to make the token total for a user change in real time after making a donation. My problem is that the Ethereum blockchain takes about 15 seconds to update the totals on-chain, and currently the reducer is reaching out to the blockchain to grab the wallet balances immediately after the donation. We don't want to make the user sit and watch a spinner for 15 seconds, but we also want the value of their wallet to reflect the transaction immediately.
One solution I can think of is to just add or subtract the proper number of tokens totally within the state of the application, and only reach out to the Ethereum API on loading the application. Is this a suitable approach? What potential issues would I be introducing?

Unlike ethereum, you can't get balance on the pending block.
You'll need to be careful deducting user's balance. Token transaction have a higher chance to fail if the gas limit is set incorrectly.

Related

Metamask: sending multiple transactions, without prompting user each time

Say, I have an interactive dapp, like a game and I want the user's actions to be saved on the blockchain (maybe these are moves in the game of chess, whatever).
So, from my understanding, options are:
Create dynamic wallet via web3, prefill it from the metamask and send as many transactions as I want.
Somehow negotiate with the user to trust the dapp and let metamask send transactions on user's behalf without pesky prompting.
What is the right option (if any)? Turns out, metamask has a whole permission escalation framework, yet I wasnt able to ask the right permission.
You can access user funds in several ways:
ask users to deposit in a smart contract and keep track of balances there
ask users to allow your smart contract to spend their tokens via ERC20 allowance
How often will user actions be saved on the blockchain?
Even if your dapp has access to all user funds via a shared wallet or ERC20 allow() + transferFrom() you'll still need somebody to trigger a transaction and pay gas fees whenever you're updating chain state.

In my web app, when should I choose to make API calls, over storing data locally?

Context:
I am working on a small "google drive" web app. I store users and their objects. Some features are premium if you buy a subscription. Recently, I started using redux because I tired of "waterfalling" things like uid from the top, to the bottom of the component tree through props.
The Problem:
My beginner-common-sense says "I should fetch subscription-status once, store it locally, and never make another subscription-status fetch again". BUT I have since run into situations where, say, the user upgrades their subscription, or it expires, and the source of truth has changed, but the local state has not.
Basically, I have a specific case where I could fetch user-state from the API EVERYTIME I load a specific component (like the landing page) OR I can fetch it once, and just be really careful about keeping local state up-to-date.
My worst fear is having out-of-sync state, like a user not having access to features they just bought.
The Question
In general, when should I:
fetch state straight from the source of truth, at the cost of redundant calls and wait time
versus
store as much state locally as possible, at the cost of added complexity when trying to keep changing state up-to-date?
Rules of Thumb, best practices, any advice is welcome!
In my opinion, you should store the subscription status locally as well, and if an user upgrades, just make sure that if the upgrade payment (or other criterion) was successful, refresh the subscription status.
Why this would be feasible is because an user is not expected to upgrade or modify their subscription status frequently.

handling data loss from third party integrations

Just curious on best practices for handling potential data loss with a third party integration.
For example, lets say that im integrating stripe for payments. If our platform has a credit system (a user needs X number of credits to do an action on the site), how would you reconcile a loss of data between the platform and after a purchase is made? Going into the example: a user is on the site, purchases a pack of credits for $10. Our platform calls stripe payment when the user clicks "purchase," the purchase is successful but all of a sudden a loss of power happens. We receive the $10 in our stripe, but on our platform the purchase was never "complete" because the loss of power happened immediately after the purchase was made, and there was no time for our system to receive the authorization code to store as completed. I'd imagine this could be common, or in another case where the purchase is complete, but there is some issue between receiving the success code from the payment processor and it causes delay. So, how do you handle this loss of data?
I could think of maybe storing a payment intent on our database with payment status "incomplete" and once a payment is made and we get a code back from stripe, then we update our database with "complete" and we have some job that polls this database every hour or something to check for "incomplete" payments.
What is common in this case?

How to get actual time in offline-first app

What would you recommend to get the GMT time in mobile application even if the user change his/her local time zone or time manually? In my app, users may take offline actions and I should record actualization time of these actions. Since this app is being used where cellular reception is low, this problem produces another consistency issues.
Any idea would matter.

How to detect expired user session in a react app?

I am developing a REST API based on Node / Express and a frontend for it based on React / Redux. Users can login (which gives them access to additional functionality) but they can use basic functionality also without logging in.
When a user logs in, the client makes an HTTP call with the credentials, the server creates a session and returns a user object (user_id and some other data) as well as a session cookie. The React app saves the user object in its Redux state. In subsequent HTTP calls, the user is authenticated through the cookie.
When rendering the user interface, the React app determines whether it is logged in or not by checking for a user object in its state. This is used to grey out some buttons which are only available to logged in users, or to hide the login link when the user is already logged in.
The problem
It could occur that the session expires, or that the user logs out in a different browser tab. The React app has no way of knowing this and thinks it is still logged in (i.e. app state mismatches reality), leading to wrong UI display.
What pattern to solve this?
Put a hook on all Ajax calls to check for 401 and update the
state?
Return session state in HTTP headers (and then?)
A Comet pattern for the server to notify the client that it has been logged out? (not a REST API anymore then)
Additional calls before actual API calls to make sure user is still logged in? (seems wasteful)
And how to deal with this once the client detects it is no longer logged in during an ongoing operation? I'd prefer to handle this in one place rather than all functions making API calls...
I'd be thankful for some best practice!
There are two straightforward ways to deal with this issue in a React application that I can think of. Both inspired by a colleague of mine few days ago.
Use SSE (server-side-events) technology to PUSH notifications. As you correctly pointed out, this makes your API less pure. This approach should be quite an acceptable sacrifice where flawless UX is required AND/OR your server might need to push other notifications to the app.
Establish a short term timer somewhere in your client app (e.g.: setTimeout(...)) that makes periodic calls to a "ping" API endpoint that will return current user/session information. This approach will impact UX for the duration of timeout, often negligible, and is commonly known as polling.
Hope this helps!
As an alternative to the naive polling, you can make it a little smarter by adding an endpoint that lets you know in how many seconds timeout is set to occur for the session at that point in time.
Then ping just before that time (instead of at a certain poll-rate) and update accordingly.
Logging out in another tab would return with an invalid token so would be picked up, too, but not as quickly if this is your main concern.
For this you could use broadcasting to let the other tabs know immediately (or use sessionStorage's change event to simulate a broadcast on unsupported browsers).
Otherwise the best way would be to implement a ServiceWorker; these can handle all requests for your app to the server. It's a centralised piece of code separate from your app that can broadcast to all tabs that a session is lost the moment it sees that one of its requests was rejected, and you can efficiently naively poll from this one place (instead of in each individual tab's runtime).
Since I am using token from the API Server that is valid for a specific period of time. So in addition to setting token in session storage I was thinking of setting up another session storage variable that stores the timestamp at which the token was generated. Then, in my js code I plan to add the validity period (say, 3600 seconds) and check if the token is still valid or not. If it is valid then the user session is valid else it is invalid.

Resources