Migrating from 5.x.x to 6.x.x
Breaking Changes & Important Updates
The most significant change in v6 is the combination of authSig
and sessionSigs
. In most functions, the client-side generated authSig
will no longer be accepted as an argument, as seen in commonly used functions like executeJs
and pkpSign
. Instead, it will be used to generate sessionSigs
to authenticate with the Lit nodes.
The migration from authSig
to sessionSigs
will not effect encryption
/decryption
features within Access Control Conditions
Only features related to our PKPs will be requiring session authentication.
Per-Package Changes
@lit-protocol/lit-node-client
executeJs
- v5 - optional use of
authSig
orsessionSigs
, but either must exist. - v6 -
sessionSigs
is strictly required
// v5
import { AuthSig, SessionSigsMap } from '@lit-protocol/types';
const authSig: AuthSig = {} // Your Auth Sig;
const sessionSigs: SessionSigsMap = {} // Your Session Sig;
const res = await litNodeClient.executeJs({
authSig: authSig,
sessionSigs: sessionSigs;
// the rest of your code...
});
// v6
import { SessionSigsMap } from '@lit-protocol/types';
const sessionSigs: SessionSigsMap = {} // Your Session Sig;
const res = await litNodeClient.executeJs({
sessionSigs,
// the rest of your code...
});
pkpSign
- v5 - optional
authSig
orsessionSigs
, but either must exist. - v6 -
sessionSigs
is strictly required
// v5
import { AuthSig, SessionSigsMap } from '@lit-protocol/types';
const authSig: AuthSig = {} // Your Auth Sig;
const sessionSigs: SessionSigsMap = {} // Your Session Sig;
const res = await litNodeClient.pkpSign({
authSig: authSig,
sessionSigs: sessionSigs;
// the rest of your code...
});
// v6
import { SessionSigsMap } from '@lit-protocol/types';
const sessionSigs: SessionSigsMap = {} // Your Session Sig;
const res = await litNodeClient.pkpSign({
sessionSigs,
// the rest of your code...
});
decryptToString
- v5 - optional
authSig
orsessionSigs
, but either must exist. - v6 -
sessionSigs
is strictly required
// v5
import * as LitJsSdk from '@lit-protocol/lit-node-client';
import { AuthSig, SessionSigsMap } from '@lit-protocol/types';
const authSig: AuthSig = {} // Your Auth Sig;
const sessionSigs: SessionSigsMap = {} // Your Session Sig;
const decryptedString = await LitJsSdk.decryptToString({
authSig: authSig,
sessionSigs: sessionSigs;
// the rest of your code...
});
// v6
import * as LitJsSdk from '@lit-protocol/lit-node-client';
import { SessionSigsMap } from '@lit-protocol/types';
const sessionSigs: SessionSigsMap = {} // Your Session Sig;
const decryptedString = await LitJsSdk.decryptToString({
sessionSigs,
// the rest of your code...
});
encryptToJson
- v5 - optional
authSig
orsessionSigs
, but either must exist. - v6 -
sessionSigs
is strictly required
// v5
import * as LitJsSdk from '@lit-protocol/lit-node-client';
import { AuthSig, SessionSigsMap } from '@lit-protocol/types';
const authSig: AuthSig = {} // Your Auth Sig;
const sessionSigs: SessionSigsMap = {} // Your Session Sig;
const encryptedJsonStr = await LitJsSdk.encryptToJson({
authSig: authSig,
sessionSigs: sessionSigs;
// the rest of your code...
});
// v6 (no auth material needed)
import * as LitJsSdk from '@lit-protocol/lit-node-client';
const encryptedJsonStr = await LitJsSdk.encryptToJson({
// the rest of your code...
});
decryptFromJson
- v5 - optional
authSig
orsessionSigs
, but either must exist. - v6 -
sessionSigs
is strictly required
// v5
import * as LitJsSdk from '@lit-protocol/lit-node-client';
import { AuthSig, SessionSigsMap } from '@lit-protocol/types';
const authSig: AuthSig = {} // Your Auth Sig;
const sessionSigs: SessionSigsMap = {} // Your Session Sig;
const decryptedFile = await LitJsSdk.decryptFromJson({
authSig: authSig,
sessionSigs: sessionSigs;
// the rest of your code...
});
// v6
import * as LitJsSdk from '@lit-protocol/lit-node-client';
import { SessionSigsMap } from '@lit-protocol/types';
const sessionSigs: SessionSigsMap = {} // Your Session Sig;
const decryptedFile = await LitJsSdk.decryptFromJson({
sessionSigs,
// the rest of your code...
});
encryptFileAndZipWithMetadata
- v5 - optional
authSig
orsessionSigs
, but either must exist. - v6 -
sessionSigs
is strictly required
// v5
import * as LitJsSdk from '@lit-protocol/lit-node-client';
import { AuthSig, SessionSigsMap } from '@lit-protocol/types';
const authSig: AuthSig = {} // Your Auth Sig;
const sessionSigs: SessionSigsMap = {} // Your Session Sig;
const encryptedData = await LitJsSdk.encryptFileAndZipWithMetadata({
authSig: authSig,
sessionSigs: sessionSigs;
// the rest of your code...
});
// v6 (no auth material needed)
import * as LitJsSdk from '@lit-protocol/lit-node-client';
const encryptedData = await LitJsSdk.encryptFileAndZipWithMetadata({
// the rest of your code...
});
decryptZipFileWithMetadata
- v5 - optional
authSig
orsessionSigs
, but either must exist. - v6 -
sessionSigs
is strictly required
// v5
import * as LitJsSdk from '@lit-protocol/lit-node-client';
import { AuthSig, SessionSigsMap } from '@lit-protocol/types';
const authSig: AuthSig = {} // Your Auth Sig;
const sessionSigs: SessionSigsMap = {} // Your Session Sig;
const decryptedData = await LitJsSdk.decryptZipFileWithMetadata({
authSig: authSig,
sessionSigs: sessionSigs;
// the rest of your code...
});
// v6
import * as LitJsSdk from '@lit-protocol/lit-node-client';
import { SessionSigsMap } from '@lit-protocol/types';
const sessionSigs: SessionSigsMap = {} // Your Session Sig;
const decryptedData = await LitJsSdk.decryptZipFileWithMetadata({
sessionSigs,
// the rest of your code...
});
@lit-protocol/constants
Getting Lit supported curves
SIGTYPE
to LIT_CURVE
// v5
import { SIGTYPE } from '@lit-protocol/constants';
export enum SIGTYPE {
BLS = 'BLS',
EcdsaK256 = 'K256',
EcdsaCaitSith = 'ECDSA_CAIT_SITH',
EcdsaCAITSITHP256 = 'EcdsaCaitSithP256',
}
// v6
import { LIT_CURVE } from '@lit-protocol/constants';
export enum LIT_CURVE {
BLS = 'BLS',
EcdsaK256 = 'K256',
EcdsaCaitSith = 'ECDSA_CAIT_SITH',
EcdsaCAITSITHP256 = 'EcdsaCaitSithP256',
}
@lit-protocol/pkp-ethers
Use PKP as an ethers signer
// v5
import { PKPEthersWallet } from '@lit-protocol/pkp-ethers';
const pkpEthersWallet = new PKPEthersWallet({
controllerAuthMethods,
controllerAuthSig,
pkpPubKey,
rpc,
litNetwork: globalThis.LitCI.network,
});
// v6
import { PKPEthersWallet } from '@lit-protocol/pkp-ethers';
const pkpEthersWallet = new PKPEthersWallet({
controllerSessionSigs,
litNodeClient,
pkpPubKey,
});
Enhancements, Fixes, and Additions
signSessionKey
In the signSessionKey
parameters, we've added three extra optional arguments for custom authentication. These arguments allow you to use your PKP to conditionally sign (via custom Lit Action code) the session key on the Lit nodes. For context, this function is typically used as the callback function for the authNeededCallback
parameter of getSessionSigs
.
For simplicity, we introduced getPkpSessionSigs
, which uses signSessionKey
under the hood.
Here's the AuthCallbackParams interface for the props
// v5
const response = await this.signSessionKey({
sessionKey: props.sessionKey,
statement: props.statement || 'Some custom statement.',
authMethods: [...params.authMethods],
pkpPublicKey: params.pkpPublicKey,
expiration: props.expiration,
resources: props.resources,
chainId: 1,
resourceAbilityRequests: props.resourceAbilityRequests,
});
// v6
const response = await this.signSessionKey({
sessionKey: props.sessionKey,
statement: props.statement || 'Some custom statement.',
authMethods: [...params.authMethods],
pkpPublicKey: params.pkpPublicKey,
expiration: props.expiration,
resources: props.resources,
chainId: 1,
resourceAbilityRequests: props.resourceAbilityRequests,
// -- optional fields
...(props.litActionCode && { litActionCode: props.litActionCode }),
...(props.ipfsId && { ipfsId: props.ipfsId }),
...(props.jsParams && { jsParams: props.jsParams }),
});
getPkpSessionSigs
Rather than creating a callback for the authNeededCallback
parameter in the getSessionSigs
function, this function creates the callback and signs the session key under the hood using the signSessionKey
function.
import { EthWalletProvider } from '@lit-protocol/lit-auth-client';
// -- preparing the parameters
const authMethod = await EthWalletProvider.authenticate({
signer: YOUR_WALLET_SIGNER,
litNodeClient,
});
const authMethodOwnedPkpPublicKey = '0x..';
const resourceAbilityRequests = [
{
resource: new LitPKPResource('*'),
ability: LitAbility.PKPSigning,
},
{
resource: new LitActionResource('*'),
ability: LitAbility.LitActionExecution,
},
];
// -- get pkp session sigs
const pkpSessionSigs = await litNodeClient.getPkpSessionSigs({
pkpPublicKey: authMethodOwnedPkpPublicKey,
authMethods: [authMethod],
resourceAbilityRequests: resourceAbilityRequests,
});
Custom Authentication
For custom authentication, you can set custom Javascript code that would be executed on Lit Action.
import { EthWalletProvider } from '@lit-protocol/lit-auth-client';
// -- preparing the parameters
const authMethod = await EthWalletProvider.authenticate({
signer: YOUR_WALLET_SIGNER,
litNodeClient,
});
const authMethodOwnedPkpPublicKey = '0x..';
const resourceAbilityRequests = [
{
resource: new LitPKPResource('*'),
ability: LitAbility.PKPSigning,
},
{
resource: new LitActionResource('*'),
ability: LitAbility.LitActionExecution,
},
];
// In a browser environment, instead of using Node.js's Buffer class
// for handling binary data and encoding it to base64,
// you can use the TextEncoder API to convert string data to a
// Uint8Array and then convert it to a base64 string using btoa() function.
const customAuthLitActionCode = Buffer.from(
`
// Works with an AuthSig AuthMethod
if (Lit.Auth.authMethodContexts.some(e => e.authMethodType === 1)) {
LitActions.setResponse({ response: "true" });
} else {
LitActions.setResponse({ response: "false" });
}
`
).toString('base64');
// -- get pkp session sigs with custom authentication
const litActionSessionSigs = await litNodeClient.getPkpSessionSigs({
pkpPublicKey: authMethodOwnedPkpPublicKey,
authMethods: [authMethod],
resourceAbilityRequests: resourceAbilityRequests,
litActionCode: customAuthLitActionCode,
jsParams: {
publicKey: authMethodOwnedPkpPublicKey,
sigName: 'custom-auth',
},
});
Crafting SIWE messages
Ever had to craft your SIWE message but were confused about the arguments to pass in? With v6, we have introduced the following helper functions:
createSiweMessage
This versatile function allows users to generate any type of SIWE message, making it perfect for advanced users. For convenience, all optional fields are pre-filled with default values. However, we recommend changing the pre-filled values for production use.
import { createSiweMessage } from '@lit-protocol/auth-helper';
// return siweMessage.prepareMessage()
const toSign: string = await createSiweMessage({
walletAddress: '',
nonce: await litNodeClient.getLatestBlockhash(),
});
createSiweMessageWithRecaps
Unlike createSiteMessage
, this function strictly requires the uri
, expiration
, and resources
arguments. It's usually used as a callback argument for the authNeededCallback
parameter in the getSessionSigs
function for EOA wallets.
import { createSiweMessageWithRecaps } from '@lit-protocol/auth-helper';
// return siweMessage.prepareMessage()
const toSign = await createSiweMessageWithRecaps({
uri: callbackParams.uri,
expiration: callbackParams.expiration,
resources: callbackParams.resourceAbilityRequests,
walletAddress: person.wallet.address,
nonce: await litNodeClient.getLatestBlockhash(),
litNodeClient: devEnv.litNodeClient,
});
Generate an authSig
generateAuthSig
As stated in the description, we still need to use authSig
mainly to generate sessionSigs
which are now the only type accepted by the Lit nodes. By utilising the generateAuthSig
function, we can ensure the structure of the authSig
object is correct.
import {
generateAuthSig,
createSiweMessageWithRecaps
} from '@lit-protocol/auth-helper';
const wallet = new ethers.Wallet.createRandom();
const preparedSiweMessage = await createSiweMessageWithRecap({...})
const authSig = await generateAuthSig({
signer: wallet,
toSign: preparedSiweMessage,
});
Clarifications
createCapacityDelegationAuthSig
There has been some confusion on the parameters for createCapacityDelegationAuthSig
, particularly capacityTokenId
, delegateeAddresses
, and uses
when delegating capacity credits.
Payment for usage of the Lit network is currently only required on the Datil
and Datil-test
networks. If you're using the datil-dev
network, payment is not required.
Below is a table detailing the expected behaviors of each:
Parameter | Provided with Values | Not Provided | Provided but Empty Array |
---|---|---|---|
capacityTokenId | Scopes the delegation to specific NFTs identified by the IDs in the array. The function will only consider the NFTs whose IDs are listed. | All NFTs owned by the user are considered eligible under the delegation. The delegation applies universally to all NFTs the user owns. | N/A |
delegateeAddresses | Restricts the use of the delegation to the addresses listed in the array. Only users whose addresses are included can utilise the delegated capabilities. | The delegation is universally applicable to anyone. There are no restrictions on who can use the delegated capabilities. | No one is allowed to use the delegated capabilities since there are no valid user addresses specified. |
uses | Sets a limit on the number of times the delegation can be used. The function enforces this limit and prevents use beyond it. | There is no limit on the number of times the delegation can be used. The capability can be used indefinitely. | Theoretically, an empty value for uses would mean no uses are possible, effectively disabling the delegation, but typically this scenario should either not be allowed by schema/logic or treated as zero, which also disables the delegation. |
Installing the Lit SDK
Install the SDK here.