Apollo GraphQL Client and Offline Storage

Technical Article

B58 Finance
3 min readNov 21, 2021

This is the first article talking about the technology of our B58 Wallet, where are going to discuss the technology used to interact with Cardano Blockchain as well as tools that we're using to build it.

In this article, we're going to focus on the Apollo Client specifically the offline feature that creates a better and more readable way to interact with data stored locally.

The new Apollo Client v3 introduces some new features like Local-Only fields and ReactiveVar where you can mark fields or entities to be client-only(Offline), which means that this data will never exist on the server-side.

We've chosen this approach because our GraphQL backend Serve is custom and built in Rust, an article about it will be released later.

Here, you can see how simple it's to query all the accounts you'll have in your Chrome Extension or Mobile App.

query GetAllAccounts {
accounts @client
}

But that's not all, the "offline like" feature available, does not hold your data through sessions which means you close your browser or the App your data is gone.

Luckily for us, the Apollo Team has done a pretty flexible solution that allows us to extend the ReactiveVar and enable it to be saved in any local storage available according to your device or Browser.

With that, we found a great suggestion from the community in the PR open for apollo library and here you can see our adaptation of it.

import { makeVar, ReactiveVar } from '@apollo/client';
import { isString } from 'lodash';
const getCleanValueForStorage = (value: unknown) => {
return isString(value) ? value : JSON.stringify(value);
};
const makeVarPersisted = <T,>(
initialValue: T,
storageName: string
): ReactiveVar<T> => {
let value = initialValue;
// Try to fetch the value from local storage
const previousValue = localStorage.getItem(storageName);
if (previousValue !== null) {
try {
const parsed = JSON.parse(previousValue);
value = parsed;
} catch {
// It wasn't JSON, assume a valid value
value = previousValue as unknown as T;
}
}
// Create a reactive var with stored/initial value
const rv = makeVar<T>(value);
const onNextChange = (newValue: T | undefined) => {
try {
// Try to add the value to local storage
if (newValue === undefined) {
localStorage.removeItem(storageName);
} else {
localStorage.setItem(
storageName,
getCleanValueForStorage(newValue));
}
} catch {
// ignore
}
// Re-register for the next change
rv.onNextChange(onNextChange);
};
// Register for the first change
rv.onNextChange(onNextChange);
return rv;
};
export default makeVarPersisted;

About B58 Finance

A next-generation, mobile and browser based wallet with an integrated DeFi platform, aiming to increase the adoption of Cardano through the familiarity of the access point.

B58 Finance wants to increase the adoption of Cardano by providing members of the general public with a familiar onboarding point that gives access to DeFi whilst simultaneously removing the complexities of the DeFi world. This will be done by presenting this world of DeFi to the users through the familiar interface of a mobile app. Viewed through a traditional financial lens this wallet and the company itself can be seen as internet or mobile bank.

Twitter: B58 Finance and @B58Wallet
Website: https://b58.finance

--

--