How to create a session key
Authorize limited actions for a specified time.
Overview
Session keys are temporary keys that are created for a specific use or duration. With FunWallets you can create session keys for a specific use case so you don’t need to continuously sign transactions.
In this guide, I’ll show you how to create a session key that has the ability to approve spend for a specific token. I will assume some basic knowledge covered in the Quick Start but I’ll quickly walk through all the steps again.
Import required objects
import {FunWallet,Auth,configureEnvironment,GlobalEnvOption,SessionKeyParams,createSessionUser,generatePrivateKey,} from "@funkit/core";
Configuring the FunWallet environment
To begin, we need to set up the environment for your FunWallet. We’ll be using the Goerli testnet and a gasless sponsor. Please visit our dashboard to receive your own production apiKey.
await configureEnvironment({chain: "goerli",gasSponsor: {sponsorAddress: "0xCB5D0b4569A39C217c243a436AC3feEe5dFeb9Ad",},apiKey: "ZrhepzWGxm74D0sqstuhT6dGrJxhoy8SZIToX6I3",});
It is important to note that the use of a gasSponsor is tied to your apiKey.
Creating Auth with a private key
We’ll use a private key as the authentication method and I’ll provide us with one.
const privateKey = generatePrivateKey();const auth = new Auth({ privateKey });
Creating FunWallet with Auth
With the Auth instance that we created in the step before, we are now able to initialize and create your FunWallet.
const funWallet = new FunWallet({users: [{ userId: auth.getAddress() }],uniqueId: auth.getWalletUniqueId(),});
Create a session key
Now that we’ve created a FunWallet, we can create a session key that has the ability to approve spend for a specific token for our FunWallet.
For this example, lets use this contract 0x712110295e4eCc0F46dC06684AA21263613b08dd which is the Fun DAI token contract address on Goerli. We can view additional details of this contract on Etherscan.
const GOERLI_FUN_DAI_ADDRESS = "0x712110295e4eCc0F46dC06684AA21263613b08dd";
Getting the Contract ABI
The first step is getting the contract ABI. This ABI serves as the interface to communicate with the smart contract. I’ll provide the relevant part of the ABI which is approve().
const ERC20_APPROVE_ABI = [{inputs: [{internalType: "address",name: "spender",type: "address",},{internalType: "uint256",name: "amount",type: "uint256",},],name: "approve",outputs: [{internalType: "bool",name: "",type: "bool",},],stateMutability: "nonpayable",type: "function",},];
Passing in the session key parameters
Now that we have the contract ABI, we have to pass in all of the relevant parameters to create our session key. Let me run over what is required:
targetWhitelist - This is where we pass in token contract that we’re using.
actionWhitelist - Here, we're defining what the session key can do. So we pass in the ABI and the specific function approve that the key can access.
deadline - We can choose how long we want the session key to be enabled as defined by epoch numbers.
user - This defines the private key of the session key that has access to approve functionality. We’ll create the private key and pass it in here.
const sessionUser = createSessionUser(); //Creating the session keyconst sessionKeyParams: SessionKeyParams = {targetWhitelist: [GOERLI_FUN_DAI_ADDRESS],actionWhitelist: [{abi: ERC20_APPROVE_ABI,functionWhitelist: ["approve"],},],deadline: Date.now(),user: sessionUser,};
Creating the session key
Once we’ve defined the session key, we can create it on chain so that it can be used.
const createSessionKeyOp = await funWallet.createSessionKey(auth,userId,sessionKeyParams);const receipt = await funWallet.executeOperation(auth, createSessionKeyOp);
Summary
Putting together all the pieces we have createSessionKey() that you can use to create session keys!
single-auth.js
import { FunWallet, Auth, configureEnvironment, GlobalEnvOption, SessionKeyParams, createSessionUser, generatePrivateKey } from "@funkit/core"// Import keysconst PRIVATE_KEY = generatePrivateKey()const API_KEY = "ZrhepzWGxm74D0sqstuhT6dGrJxhoy8SZIToX6I3"const GOERLI_FUN_DAI_ADDRESS = "0x712110295e4eCc0F46dC06684AA21263613b08dd"const ERC20_APPROVE_ABI = [{ inputs: [ { internalType: "address", name: "spender", type: "address" }, { internalType: "uint256", name: "amount", type: "uint256" } ],name: "approve",outputs: [ { internalType: "bool", name: "", type: "bool" } ],stateMutability: "nonpayable",type: "function" }]const options: GlobalEnvOption = {chain: "goerli",gasSponsor: {sponsorAddress: "0xCB5D0b4569A39C217c243a436AC3feEe5dFeb9Ad"},apiKey: API_KEY}const createSessionKey = async () => {await configureEnvironment(options)const auth = new Auth({ privateKey: PRIVATE_KEY })const userId = await auth.getUserId()const funWallet = new FunWallet({users: [{ userId: userId }],uniqueId: await auth.getWalletUniqueId()})const sessionUser = createSessionUser()const sessionKeyParams: SessionKeyParams = {targetWhitelist: [GOERLI_FUN_DAI_ADDRESS],actionWhitelist: [{abi: ERC20_APPROVE_ABI,functionWhitelist: ["approve"]}],deadline: Date.now(),user: sessionUser}const createSessionKeyOp = await funWallet.createSessionKey(auth, userId, sessionKeyParams)const receipt = await funWallet.executeOperation(auth, createSessionKeyOp)console.log(receipt)}createSessionKey()