Skip to main content

Session Key

Notice
  • This function is experimental and currently only available on the testnet network
  • This function is only for the Popup SDK

Background

A session key is a temporary key that users can generate on the application side. UniPass users can authorize session keys to reduce the need for UniPass to request user's signature operations. By authorizing the application to operate user assets within certain requirements, it enables the best user experience.

When authorizing a session key, users will generate a permit that specifies the operations that the session key can perform.

When generating a permit, you can restrict the session key in the following ways:

  • Validity period: authorization time, start time and expiration time of authorization
  • Specific chain ID: can only be used on a certain chain
  • Interaction whitelist contract: can only interact with contract addresses specified in the whitelist
  • Specific currency: can only operate specific tokens
  • Maximum single transaction limit
  • Daily cumulative transaction limit
Notice
  • The current session key authorization only supports validity period (defaulted to 7 days in the SDK). The authorized session key can transfer user assets directly.
  • The current session key function is meant only for experimental development and testing, and cannot be used in a production environment.

Initialize Session Key

This feature is only available for Popup SDK. For more information about Popup SDK, please refer to: SDK initialization, Connect UniPass Wallet.

Install Specified Version of SDK

npm install unipasswallet/popup-sdk@1.1.5-alpha.2

Added parameter description for sessionKeyAddress:

  • sessionKeyAddress: Ethereum address of the session key.

Code Sample

try {
const account = await upWallet.login({
email: true,
eventListener: (event: UPEvent) => {
console.log("event", event);
const { type, body } = event;
if (type === UPEventType.REGISTER) {
console.log("account", body);
ElMessage.success("a user register");
}
},
connectType: "both",
sessionKeyAddress: "your session key address",
});
const { address, email } = account;
console.log("account", address, email);
} catch (err) {
console.log("connect err", err);
}

Return: After successfully connecting to UniPass, the result will be data of type UPAccount. If the user denies connection to UniPass Wallet, an exception will be thrown. The application should catch this exception and handle it.

export interface UPAccount {
address: string; // Ethereum address of user
email?: string | undefined; // Email
newborn?: boolean | undefined; // Newly registered or not
message?: string; // sign with ethereum message when authorize is true
signature?: string; // sign with ethereum signature when authorize is true
sessionKeyPermit?: string; // sessionKeyPermit if pass sessionKeyAddress when login, it is a json string that contains timestamp, weight and permit
}

Obtain Session Key Permit

Get Wallet through UPAccount

  • upAccount: UPAccount information obtained when login
import { Wallet } from "@unipasswallet/wallet";
import { Keyset } from "@unipasswallet/keys";
import { RpcRelayer } from "@unipasswallet/relayer";
import { providers, utils } from "ethers";
import { TESTNET_UNIPASS_WALLET_CONTEXT } from "@unipasswallet/network";

const provider = new providers.JsonRpcProvider("rpcUrl");
const relayer = new RpcRelayer(
"https://testnet.wallet.unipass.vip/relayer-v2-goerli",
TESTNET_UNIPASS_WALLET_CONTEXT,
provider
);
let upAccount: UPAccount;
const wallet = new Wallet({
address: upAccount.address,
keyset: new Keyset([]), // 由session key签名, 因此传空值
provider,
relayer,
});

Obtaining Session Key Permit through UPAccount

  • sessionKeyEoaWallet: Wallet address generated by the private key of sessionKeyAddress, usually obtained from ethers.Wallet.createRandom()
import { SignType } from "@unipasswallet/keys";

const permit: IPermit = JSON.parse(upAccount.sessionKeyPermit);
const sessionKey = new SessionKey(
sessionKeyEoaWallet,
SignType.EthSign,
upAccount.address,
permit
);
export enum SignType {
EIP712Sign = 1, // Signed via EIP712
EthSign = 2, // Signed via Personal Sign, fixed to `SignType.EthSign`
}

export interface IPermit {
readonly timestamp: number; // SessionKey expiration time
readonly weight: number; // SessionKey weight, valid if >= 100
readonly permit: string; // UniPass Wallet authorization signature
}

Sending Transactions via Session Key

  • nonce: UniPass Wallet nonce
  • revertOnError: Revert if the transaction fails
  • gasLimit: Transaction gas limit; set to 0 for no limit
  • target: Transaction target address
  • data: Transaction input data
import { CallTxBuilder } from "@unipasswallet/transaction-builders";

const nonce = await wallet.getNonce();
const tx = new CallTxBuilder(
revertOnError,
gasLimit,
target,
value,
data
).build();
const ret = await wallet.sendTransactions(
new RawMainExecuteCall(tx, nonce, sessionKey)
);
const receipt = await ret.wait();

Sign with Session Key

  • messageHash: The hash of the message to be signed.
const signature = await wallet.signMessage(arrayify(messageHash), sessionKey);

Verifying Messages from Session Key

For how to verify the signature from session key on server, please refer to: UniPass Verifying Messages