Coinbase team is soon going to add Session Keys support to the Smart Wallet!
Currently, you can play with/test the Coinbase Smart Wallet with Session Keys on Testnet by following the guide here.
If you have already been testing Session Keys you may have noticed that whenever you make a change to your frontend you need to redo the process of granting permissions, this is because permissionsContext and credential which are important variables required to perform transaction using Session Keys are state variables that get destroyed on hot refresh triggered every time you make a change.
Here is an example.
This can be very frustrating during the development process.
The official guide does mention this and suggest that we can persist permissionsContext and credential variables in IndexedDB
You should have already integrated smart wallet into your dApp (here's a guide if you haven't) along with Session Keys support. This guide does not go over the integration part.
The getDatabase takes in a key and tries to get the objectStore if it does not exist if creates it along with the schema.
The function openDB tries to open the version 1 of db called cbsw.
The openDB function also takes in a upgrade function, the upgrade function is called when we try to open version 1 of cbsw db and it does not exist.
So the upgrade function is the right place to define the schema, since it will called when we try to open the db the first time because it does not exist.
Inside the upgrade function we check if the objectStores permissionsContext and credential already exists.
if(!db.objectStoreNames.contains(key)){
// objectStores do not exist.
}
Since they don't we can create the objectStores using createObjectStore which takes in the name and some optional properties, in our case keyPath which is used to specify the column/property we will use to search values in the objectStore.
In our example, the property we will use to search on both objectStores is address, more on that later.
We can now create indexes using createIndex for the both objectStores, in our example below we are creating an index named address where the keyPath is address and we want to enforce address property to be unique.
We want to enforce uniqueness on the address property because if the user has multiple smart wallets connected to your dApp and each of them have session keys associated with them then you want your dApp to be able to load the session keys respective to the smart wallet that is currently connected which you can do by searching the objectStore using the connected smart wallet's address.
Let's now use a useEffect to create/load the db when the dApp mounts.
In the code below initDB is the called first when the dApp mounts and then everytime the key (the objectStore to access) or the connected wallet address changes.
Once we get the DB, we can search for the value we are looking for using the objectStore name and connected wallet address.
The value retrieved can then be loaded onto state.
Depending on the key (credential or context) we load the value and set the respective as the state, this has to be done because the type of value is different for credential and context.
Let's now write another useEffect which will update the values in IndexedDB when the React state values change.
The saveToDB function is called when the frontend dApp changes the credential and permissionsContext value, so that the updated state values can then be stored in IndexedDB.
Depending on the key to useIndexedDBState the value is stored in the respective format.
We store the value using db.put which takes in the objectStore name and the value we want to store, in our example we store both the connected wallet address address and the value (state value of credential or context).