Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
be3d59a
chore(PR): init
Ansonhkg Aug 13, 2025
205f686
chore(PR): init
Ansonhkg Aug 13, 2025
99e5f5c
chore(PR): init branch
Ansonhkg Aug 13, 2025
0c88db1
feat(wip): add pre-generated materials support
Ansonhkg Aug 14, 2025
70c5bc7
Merge branch 'naga' into feature/jss-36-naga-sdk-add-a-make-a-request…
Ansonhkg Aug 25, 2025
14d6124
Merge branch 'naga' into feature/jss-36-naga-sdk-add-a-make-a-request…
Ansonhkg Aug 25, 2025
1e91e94
Merge branch 'feature/jss-36-naga-sdk-add-a-make-a-request-function-t…
Ansonhkg Aug 25, 2025
dfaca3f
Merge branch 'naga' into feature/jss-36-naga-sdk-add-a-make-a-request…
Ansonhkg Oct 14, 2025
1d2dbe0
refactor(getPkpAuthContext): improve logging format for delegationAut…
Ansonhkg Oct 14, 2025
82d33f1
feat(validateDelegationAuthSig): add function to validate delegation …
Ansonhkg Oct 14, 2025
6c9f0f6
feat(auth): enhance delegation signature handling and validation in a…
Ansonhkg Oct 14, 2025
27c9645
Merge branch 'naga' into feature/jss-36-naga-sdk-add-a-make-a-request…
Ansonhkg Oct 15, 2025
c74ae30
feat(validateDelegationAuthSig): add unit tests for delegation signat…
Ansonhkg Oct 15, 2025
720830d
feat(auth): export `validateDelegationAuthSig` helper
Ansonhkg Oct 15, 2025
be3eb44
fix(auth): validateDelegationAuthSig params
Ansonhkg Oct 15, 2025
de1fa5a
Merge branch 'feature/jss-36-naga-sdk-add-a-make-a-request-function-t…
Ansonhkg Oct 15, 2025
c5bc50e
feat(auth): derive recap metadata for pre-generated PKP contexts
Ansonhkg Oct 16, 2025
f6152f6
feat(auth): add test
Ansonhkg Oct 16, 2025
dd2bac9
fmt
Ansonhkg Oct 16, 2025
eb2138f
feat(ci): add test to ci
Ansonhkg Oct 16, 2025
a9381e8
Merge branch 'naga' into feature/jss-36-naga-sdk-add-a-make-a-request…
Ansonhkg Oct 16, 2025
83cf3cf
feat(e2e): centralise pre-generated delegation reuse helper
Ansonhkg Oct 16, 2025
29d011a
Merge branch 'feature/jss-36-naga-sdk-add-a-make-a-request-function-t…
Ansonhkg Oct 16, 2025
68ffaa9
refactor(tests): update createPregenDelegationServerReuseTest to acce…
Ansonhkg Oct 16, 2025
b6c9d9d
refactor(network): replace networkName with resolvedNetwork in variou…
Ansonhkg Oct 16, 2025
1930dea
fmt
Ansonhkg Oct 16, 2025
4c0da86
fix(tests): simplify test syntax
Ansonhkg Oct 16, 2025
3ec43bd
Merge branch 'naga' into feature/jss-36-naga-sdk-add-a-make-a-request…
Ansonhkg Oct 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/auth-helpers/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export * from './lib/generate-auth-sig';
export * from './lib/models';
export * from './lib/recap/recap-session-capability-object';
export * from './lib/recap/resource-builder';
export * from './lib/recap/utils';
export * from './lib/resources';
export * from './lib/session-capability-object';
export * from './lib/siwe/create-siwe-message';
Expand Down
52 changes: 52 additions & 0 deletions packages/auth-helpers/src/lib/recap/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,55 @@ export function getRecapNamespaceAndAbility(litAbility: LIT_ABILITY_VALUES): {
);
}
}

export const RESOLVED_AUTH_CONTEXT_PREFIX = 'lit-resolvedauthcontext://';
const PAYMENT_DELEGATION_PREFIX = 'lit-paymentdelegation://';
const PKP_PREFIX = 'lit-pkp://';
const ACC_PREFIX = 'lit-accesscontrolcondition://';

/**
* Reverse mapping from Recap namespace/ability to LitAbility.
* Returns null when the recap entry only carries metadata (eg. resolved auth context).
*/
export function getLitAbilityFromRecap(params: {
recapNamespace: string;
recapAbility: string;
resourceKey: string;
}): LIT_ABILITY_VALUES | null {
const { recapNamespace, recapAbility, resourceKey } = params;

if (recapNamespace === LIT_NAMESPACE.Threshold) {
if (recapAbility === LIT_RECAP_ABILITY.Decryption) {
return LIT_ABILITY.AccessControlConditionDecryption;
}

if (recapAbility === LIT_RECAP_ABILITY.Execution) {
return LIT_ABILITY.LitActionExecution;
}

if (recapAbility === LIT_RECAP_ABILITY.Signing) {
if (resourceKey.startsWith(PKP_PREFIX)) {
return LIT_ABILITY.PKPSigning;
}
if (resourceKey.startsWith(ACC_PREFIX)) {
return LIT_ABILITY.AccessControlConditionSigning;
}
}
}

if (
recapNamespace === LIT_NAMESPACE.Auth &&
recapAbility === LIT_RECAP_ABILITY.Auth
) {
if (resourceKey.startsWith(PAYMENT_DELEGATION_PREFIX)) {
return LIT_ABILITY.PaymentDelegation;
}

if (resourceKey.startsWith(RESOLVED_AUTH_CONTEXT_PREFIX)) {
// Resolved auth context entries only contain metadata.
return null;
}
}

return null;
}
19 changes: 18 additions & 1 deletion packages/auth-helpers/src/lib/resources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,13 @@ import {
import { AccessControlConditions, ILitResource } from '@lit-protocol/types';
import { formatPKPResource } from './utils';

const RESOLVED_AUTH_CONTEXT_PREFIX = 'lit-resolvedauthcontext';
type InternalResourcePrefix =
| LIT_RESOURCE_PREFIX_VALUES
| typeof RESOLVED_AUTH_CONTEXT_PREFIX;

abstract class LitResourceBase {
abstract resourcePrefix: LIT_RESOURCE_PREFIX_VALUES;
abstract resourcePrefix: InternalResourcePrefix;
public readonly resource: string;

constructor(resource: string) {
Expand Down Expand Up @@ -158,6 +163,18 @@ export function parseLitResource(resourceKey: string): ILitResource {
return new LitActionResource(
resourceKey.substring(`${LIT_RESOURCE_PREFIX.LitAction}://`.length)
);
} else if (resourceKey.startsWith(RESOLVED_AUTH_CONTEXT_PREFIX)) {
const resource = resourceKey.substring(
`${RESOLVED_AUTH_CONTEXT_PREFIX}://`.length
);

return {
resourcePrefix: RESOLVED_AUTH_CONTEXT_PREFIX,
resource,
getResourceKey: () => `${RESOLVED_AUTH_CONTEXT_PREFIX}://${resource}`,
toString: () => `${RESOLVED_AUTH_CONTEXT_PREFIX}://${resource}`,
isValidLitAbility: () => false,
} as unknown as ILitResource;
}
throw new InvalidArgumentException(
{
Expand Down
27 changes: 27 additions & 0 deletions packages/auth/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,33 @@ export { getAuthIdByAuthMethod } from './lib/authenticators/helper/utils';
* @returns {SessionKeyPair} The generated session key pair.
*/
export { generateSessionKeyPair } from './lib/AuthManager/utils/generateSessionKeyPair';
export { validateDelegationAuthSig } from './lib/AuthManager/utils/validateDelegationAuthSig';

/**
* Utility function to generate a PKP delegation auth signature for a given session key pair.
* The PKP will sign the session key delegation message via Lit nodes.
* This function is useful for server-side scenarios where you want to pre-generate
* PKP session materials and reuse them across multiple requests.
*/
export { generatePkpDelegationAuthSig } from './lib/AuthManager/authAdapters/generatePkpDelegationAuthSig';

/**
* Utility function to generate an EOA delegation auth signature for a given session key pair.
* The EOA wallet will sign the session key delegation message directly.
* This function is useful for server-side scenarios where you want to pre-generate
* EOA session materials and reuse them across multiple requests.
*/
export { generateEoaDelegationAuthSig } from './lib/AuthManager/authAdapters/generateEoaDelegationAuthSig';

/**
* Utility function to create a PKP auth context from pre-generated session materials.
* This is a streamlined API for server-side scenarios where session materials
* are generated once and reused across multiple requests.
*
* This function only requires the essential parameters (pkpPublicKey, sessionKeyPair, delegationAuthSig)
* and extracts auth config information from the delegation signature automatically.
*/
export { getPkpAuthContextFromPreGeneratedAdapter } from './lib/AuthManager/authAdapters/getPkpAuthContextFromPreGeneratedAdapter';

// ============================== Authenticators ==============================
export {
Expand Down
36 changes: 31 additions & 5 deletions packages/auth/src/lib/AuthManager/auth-manager.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { getChildLogger } from '@lit-protocol/logger';
import { AuthData, HexPrefixedSchema } from '@lit-protocol/schemas';
// import { AuthSig, SessionKeyPair } from '@lit-protocol/types';
import { AuthSig, SessionKeyPair } from '@lit-protocol/types';
import { z } from 'zod';
import { AuthConfigV2 } from '../authenticators/types';
import type { LitAuthStorageProvider } from '../storage/types';
Expand All @@ -11,7 +11,9 @@ import {
import { getPkpAuthContextAdapter } from './authAdapters/getPkpAuthContextAdapter';
import { AuthConfigSchema } from './authContexts/BaseAuthContextType';
import { getCustomAuthContextAdapter } from './authAdapters/getCustomAuthContextAdapter';
import { hexToBigInt, keccak256, toBytes } from 'viem';
import { generatePkpDelegationAuthSig } from './authAdapters/generatePkpDelegationAuthSig';
import { generateEoaDelegationAuthSig } from './authAdapters/generateEoaDelegationAuthSig';
import { getPkpAuthContextFromPreGeneratedAdapter } from './authAdapters/getPkpAuthContextFromPreGeneratedAdapter';

export interface AuthManagerParams {
storage: LitAuthStorageProvider;
Expand Down Expand Up @@ -77,12 +79,19 @@ export const createAuthManager = (authManagerParams: AuthManagerParams) => {
cache?: {
delegationAuthSig?: boolean;
};
// Optional pre-generated auth materials for server-side usage
// sessionKeyPair?: SessionKeyPair;
// delegationAuthSig?: AuthSig;
sessionKeyPair?: SessionKeyPair;
delegationAuthSig?: AuthSig;
}) => {
return getPkpAuthContextAdapter(authManagerParams, params);
},
createPkpAuthContextFromPreGenerated: (params: {
pkpPublicKey: z.infer<typeof HexPrefixedSchema>;
sessionKeyPair: SessionKeyPair;
delegationAuthSig: AuthSig;
authData?: AuthData;
}) => {
return getPkpAuthContextFromPreGeneratedAdapter(params);
},
createCustomAuthContext: (params: {
// authData: AuthData;
pkpPublicKey: z.infer<typeof HexPrefixedSchema>;
Expand All @@ -104,5 +113,22 @@ export const createAuthManager = (authManagerParams: AuthManagerParams) => {

return getCustomAuthContextAdapter(authManagerParams, params);
},
generatePkpDelegationAuthSig: (params: {
pkpPublicKey: z.infer<typeof HexPrefixedSchema>;
authData: AuthData;
sessionKeyPair: SessionKeyPair;
authConfig: AuthConfigV2;
litClient: BaseAuthContext<any>['litClient'];
}) => {
return generatePkpDelegationAuthSig(authManagerParams, params);
},
generateEoaDelegationAuthSig: (params: {
account: any; // ExpectedAccountOrWalletClient type
sessionKeyPair: SessionKeyPair;
authConfig: AuthConfigV2;
litClient: BaseAuthContext<any>['litClient'];
}) => {
return generateEoaDelegationAuthSig(authManagerParams, params);
},
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import { AUTH_METHOD_TYPE } from '@lit-protocol/constants';
import { getChildLogger } from '@lit-protocol/logger';
import { AuthConfigSchema } from '@lit-protocol/schemas';
import { AuthSig, SessionKeyPair } from '@lit-protocol/types';
import { z } from 'zod';
import { AuthConfigV2 } from '../../authenticators/types';
import { LitAuthData } from '../../types';
import { AuthManagerParams } from '../auth-manager';
import {
ExpectedAccountOrWalletClient,
getEoaAuthContext,
} from '../authContexts/getEoaAuthContext';
import { processResources } from '../utils/processResources';
import { WalletClientAuthenticator } from '../../authenticators/WalletClientAuthenticator';
import { ViemAccountAuthenticator } from '../../authenticators/ViemAccountAuthenticator';

const _logger = getChildLogger({
module: 'generateEoaDelegationAuthSig',
});

/**
* Generates an EOA delegation auth signature for a given session key pair.
* The EOA wallet will sign the session key delegation message directly.
* This function is useful for server-side scenarios where you want to pre-generate
* EOA session materials and reuse them across multiple requests.
*
* @param upstreamParams - Auth manager parameters including storage
* @param params - Parameters for generating the EOA delegation signature
* @returns The delegation auth signature (AuthSig) signed by the EOA wallet
*/
export async function generateEoaDelegationAuthSig(
upstreamParams: AuthManagerParams,
params: {
account: ExpectedAccountOrWalletClient;
sessionKeyPair: SessionKeyPair;
authConfig: AuthConfigV2;
litClient: {
getContext: () => Promise<any>;
};
}
): Promise<AuthSig> {
_logger.info(
{
hasAccount: !!params.account,
hasSessionKeyPair: !!params.sessionKeyPair,
},
'generateEoaDelegationAuthSig: Starting EOA delegation signature generation'
);

const _resources = processResources(params.authConfig.resources);

// Get network context from litClient for nonce
const litClientCtx = await params.litClient.getContext();

// Create a minimal LitAuthData structure with the provided session key pair
const litAuthData: LitAuthData = {
sessionKey: {
keyPair: params.sessionKeyPair,
expiresAt: params.authConfig.expiration!,
},
// For EOA, we use EthWallet as the auth method type
authMethodType: AUTH_METHOD_TYPE.EthWallet,
};

// Determine the authenticator based on account type
let authenticatorClass;
if (
'account' in params.account &&
params.account.account?.type === 'json-rpc'
) {
// WalletClient
authenticatorClass = WalletClientAuthenticator;
} else {
// Viem Account
authenticatorClass = ViemAccountAuthenticator;
}

// Create auth config for validation
const authConfigForValidation = {
...params.authConfig,
resources: _resources,
};
const validatedAuthConfig = AuthConfigSchema.parse(authConfigForValidation);

// Call getEoaAuthContext which will generate the delegation signature
const authContext = await getEoaAuthContext({
authentication: {
authenticator: authenticatorClass,
account: params.account,
},
authConfig: validatedAuthConfig,
deps: {
nonce: litClientCtx.latestBlockhash,
authData: litAuthData,
},
});

// Get the delegation signature from the auth context
const delegationAuthSig = await authContext.authNeededCallback();

_logger.info(
{
hasSignature: !!delegationAuthSig,
},
'generateEoaDelegationAuthSig: EOA delegation signature generated successfully'
);

return delegationAuthSig as AuthSig;
}
Loading
Loading