Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
180 changes: 180 additions & 0 deletions e2e/src/tickets/jss11.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
import { ViemAccountAuthenticator } from '@lit-protocol/auth';
import { createLitClient } from '@lit-protocol/lit-client';
import { nagaDev } from '@lit-protocol/networks';
import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts';
import { Account } from 'viem';
import { fundAccount } from '../helper/fundAccount';

const NETWORK_MODULE = nagaDev;
const LIVE_MASTER_ACCOUNT = process.env['LIVE_MASTER_ACCOUNT'] as `0x${string}`;
const LIVE_NETWORK_FUNDING_AMOUNT = '0.01';

describe('JSS-11: PKP Management and Pagination', () => {
let masterViemAccount: Account;
let randomViemAccount: Account;
let viemAccountAuthData: Awaited<
ReturnType<typeof ViemAccountAuthenticator.authenticate>
>;
let litClient: Awaited<ReturnType<typeof createLitClient>>;

beforeAll(async () => {
// ---------- Authentication Layer ----------
masterViemAccount = privateKeyToAccount(LIVE_MASTER_ACCOUNT);
randomViemAccount = privateKeyToAccount(generatePrivateKey());

await fundAccount(randomViemAccount, masterViemAccount, NETWORK_MODULE, {
ifLessThan: '0',
thenFundWith: LIVE_NETWORK_FUNDING_AMOUNT,
});

viemAccountAuthData = await ViemAccountAuthenticator.authenticate(
randomViemAccount
);

// ---------- Client Setup Layer ----------
litClient = await createLitClient({
network: NETWORK_MODULE,
});
});

describe('Initial State Tests', () => {
it('should return empty array for new account with no PKPs', async () => {
const result = await litClient.viewPKPsByAuthData({
authData: viemAccountAuthData,
pagination: { limit: 10, offset: 0 },
});

expect(result.pkps.length).toBe(0);
});
});

describe('PKP Creation and Management', () => {
it('should mint first PKP successfully', async () => {
// Mint PKP
await litClient.mintWithAuth({
account: randomViemAccount,
authData: viemAccountAuthData,
scopes: ['sign-anything'],
});

// Verify PKP exists
const result = await litClient.viewPKPsByAuthData({
authData: viemAccountAuthData,
pagination: { limit: 10, offset: 0 },
});

expect(result.pkps.length).toBe(1);
});

it('should mint second PKP and return both PKPs', async () => {
// Mint second PKP
await litClient.mintWithAuth({
account: randomViemAccount,
authData: viemAccountAuthData,
scopes: ['sign-anything'],
});

// Verify both PKPs exist
const result = await litClient.viewPKPsByAuthData({
authData: viemAccountAuthData,
pagination: { limit: 10, offset: 0 },
});

expect(result.pkps.length).toBe(2);
});
});

describe('Pagination Functionality', () => {
it('should respect limit parameter', async () => {
const result = await litClient.viewPKPsByAuthData({
authData: viemAccountAuthData,
pagination: { limit: 1, offset: 0 },
});

expect(result.pkps.length).toBe(1);
});

it('should respect offset parameter and return different PKPs', async () => {
// Get first PKP
const firstResult = await litClient.viewPKPsByAuthData({
authData: viemAccountAuthData,
pagination: { limit: 1, offset: 0 },
});

// Get second PKP
const secondResult = await litClient.viewPKPsByAuthData({
authData: viemAccountAuthData,
pagination: { limit: 1, offset: 1 },
});

expect(firstResult.pkps.length).toBe(1);
expect(secondResult.pkps.length).toBe(1);
expect(firstResult.pkps[0].tokenId).not.toBe(
secondResult.pkps[0].tokenId
);
});

it('should handle large limit values correctly', async () => {
const result = await litClient.viewPKPsByAuthData({
authData: viemAccountAuthData,
pagination: { limit: 100, offset: 0 },
});

// Should return all PKPs (currently 2)
expect(result.pkps.length).toBe(2);
});

it('should handle offset beyond available PKPs', async () => {
const result = await litClient.viewPKPsByAuthData({
authData: viemAccountAuthData,
pagination: { limit: 10, offset: 10 },
});

expect(result.pkps.length).toBe(0);
});
});

describe('Data Consistency Tests', () => {
it('should return consistent results across multiple calls', async () => {
// Get PKPs multiple times
const firstCall = await litClient.viewPKPsByAuthData({
authData: viemAccountAuthData,
pagination: { limit: 10, offset: 0 },
});

const secondCall = await litClient.viewPKPsByAuthData({
authData: viemAccountAuthData,
pagination: { limit: 10, offset: 0 },
});

expect(secondCall.pkps.length).toBe(firstCall.pkps.length);
expect(secondCall.pkps.map((p) => p.tokenId).sort()).toEqual(
firstCall.pkps.map((p) => p.tokenId).sort()
);
});

it('should maintain correct PKP data structure', async () => {
const result = await litClient.viewPKPsByAuthData({
authData: viemAccountAuthData,
pagination: { limit: 1, offset: 0 },
});

expect(result.pkps.length).toBe(1);
const pkp = result.pkps[0];

// Verify PKP has required properties
expect(pkp).toHaveProperty('tokenId');
expect(pkp).toHaveProperty('publicKey');
expect(pkp).toHaveProperty('ethAddress');

// Verify data types
expect(typeof pkp.tokenId).toBe('string');
expect(typeof pkp.publicKey).toBe('string');
expect(typeof pkp.ethAddress).toBe('string');

// Verify format
expect(pkp.publicKey).toMatch(/^0x[a-fA-F0-9]+$/);
expect(pkp.ethAddress).toMatch(/^0x[a-fA-F0-9]{40}$/);
});
});
});
3 changes: 1 addition & 2 deletions packages/lit-client/src/lib/LitClient/createLitClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -836,7 +836,6 @@ export const _createNagaLitClient = async (
}
| AuthData;
pagination?: { limit?: number; offset?: number };
storageProvider?: PKPStorageProvider;
}) => {
// Use read-only account for viewing PKPs
const account = privateKeyToAccount(
Expand All @@ -846,7 +845,7 @@ export const _createNagaLitClient = async (
return await networkModule.chainApi.getPKPsByAuthData({
authData: params.authData,
pagination: params.pagination,
storageProvider: params.storageProvider,
// storageProvider: params.storageProvider,
account,
});
},
Expand Down
Loading