Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: ability to add scope when minting through relayer #251

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
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,21 @@ export async function main() {
accessToken: JSON.stringify(LITCONFIG.CONTROLLER_AUTHSIG_2),
};

// -- setting scope for the auth method
// https://developer.litprotocol.com/v3/sdk/wallets/auth-methods/#auth-method-scopes
const options = {
permittedAuthMethodScopes: [[1]],
};

let pkps = await authProvider.fetchPKPsThroughRelayer(authMethod);

if (pkps.length <= 0) {
try {
await authProvider.mintPKPThroughRelayer(authMethod);
const auth = await authProvider.mintPKPThroughRelayer(
authMethod,
options
);
console.log('auth', auth);
} catch (e) {
return fail('Failed to mint PKP');
}
Expand All @@ -46,6 +56,8 @@ export async function main() {
// convert BigNumber to string
pkp.tokenId = ethers.BigNumber.from(pkp.tokenId).toString();

console.log('pkp', pkp);

const pkpPubKey = pkp.publicKey;

const sessionKeyPair = client.getSessionKey();
Expand Down
30 changes: 15 additions & 15 deletions lit.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,27 +18,27 @@
"AUTH_METHOD_ACCESS_TOKEN": "<your access token here>",
"CONTROLLER_PRIVATE_KEY": "f21d3fafe29fa10d26092ce4e91cd7108b734b98393f79b3c2cd04de24ca6817",
"CONTROLLER_ADDRESS": "0xeF71c2604f17Ec6Fc13409DF24EfdC440D240d37",
"PKP_TOKENID": "36493824178644046451512765955837370026174905534359700419036305432519574874952",
"PKP_PUBKEY": "04fc640ce59f2941109aa117aeae74f2597740a98bc3b18bad6a60ff79afa825c0383863d97ff6ec4febfee5a3e9411a604371ef2b6323de8c56ca9e7c64884e49",
"PKP_ETH_ADDRESS": "0xf86B3579Cc27E2c6855d396f14dB554F0becED91",
"PKP_COSMOS_ADDRESS": "cosmos12jewzl90qrdrx30acygp0xza0ur7xvs5k3lpte",
"PKP_SUI_ADDRESS": "0xe0b00390a0123e2706176bef210f10217dbcc0f94b226f09c73c38cd839359d9",
"PKP_TOKENID": "78594425786398933492991088588977337141561051438961247304131708488787796653557",
"PKP_PUBKEY": "04e37c9693f13a8cf33281a8e2a9693571d2661b951e757d530ad5849b8f3fbda867a6069728aec71dd8280747489943bb0f74c23851f901f1e75c738bd6582137",
"PKP_ETH_ADDRESS": "0x17516921432A8013c98D1A8c690f628Bd454f95E",
"PKP_COSMOS_ADDRESS": "cosmos10qx4xek3cgqhm5v54chm6qcl6z7tkv6hlsgwmh",
"PKP_SUI_ADDRESS": "0x89b5242ca86fa37cab0447b6eff19935a074daf648546901ec7ce1057eaad02c",
"CONTROLLER_AUTHSIG": {
"sig": "0x78d58943441b2f94c8568d08aa3346e2d1d8ccd6733d039de298af16bb9fe9ca162ef8be7458ae62c2633d6b0cf839807ea9d10aaba31218061dc7472c9c0e5c1c",
"sig": "0x8a731a803470714f0b80d7db2401d597612bd3809d48e822f86098635a7fe50651cb5e3c04fb9e0608be150dcae2ff58c0700157fa1d6fd76e085a7cb51718381c",
"derivedVia": "web3.eth.personal.sign",
"signedMessage": "localhost wants you to sign in with your Ethereum account:\n0xeF71c2604f17Ec6Fc13409DF24EfdC440D240d37\n\nTESTING TESTING 123\n\nURI: https://localhost/login\nVersion: 1\nChain ID: 1\nNonce: E8NnQ74rcoslAlkdy\nIssued At: 2023-10-03T14:32:02.839Z\nExpiration Time: 2215-05-30T14:32:02.839Z",
"signedMessage": "localhost wants you to sign in with your Ethereum account:\n0xeF71c2604f17Ec6Fc13409DF24EfdC440D240d37\n\nTESTING TESTING 123\n\nURI: https://localhost/login\nVersion: 1\nChain ID: 1\nNonce: 6q3xCmn2kBTuYneUO\nIssued At: 2023-11-07T16:21:02.439Z\nExpiration Time: 2215-07-04T16:21:02.439Z",
"address": "0xeF71c2604f17Ec6Fc13409DF24EfdC440D240d37"
},
"CONTROLLER_ADDRESS_2": "0xeF71c2604f17Ec6Fc13409DF24EfdC440D240d37",
"PKP_TOKENID_2": "57909217325940649169986093009266550714927195611572100041506720187005637918925",
"PKP_PUBKEY_2": "04823386642aa7101404f6365ccfabb01f4db3ec08da27626772876d2de721d6c55d611f8a858843922da24d10c163af5d17a95f5d17da4b89606cadc051a0d0b3",
"PKP_ETH_ADDRESS_2": "0xba2D4Ede4a4B2ae085f4644337873Deec56468a9",
"PKP_COSMOS_ADDRESS_2": "cosmos1lqyy4ajqr3vurfhk85tdspmhmwm5zmpfhjwk24",
"PKP_SUI_ADDRESS_2": "0xc49afd2ada20436312e4f683746e610c2b5b3bf2fa3e7997a90e35024df350fd",
"PKP_TOKENID_2": "90043808743213090122662525503007871977280203802972152862903787232930283856165",
"PKP_PUBKEY_2": "04bcbfe53e72571463c1d3d112d7c9ec3f7acb702796a7e91aa1ee955ce0a26670dd666de5236dcbb5f3001961cf9626d1133c8c0bedce2fbd518a5b5911444413",
"PKP_ETH_ADDRESS_2": "0x2835ac36a36017796F4ef1708f7eb053f25f69d5",
"PKP_COSMOS_ADDRESS_2": "cosmos18tn059c3wx9w9psy0rlayzdz89r0nhxxes0de5",
"PKP_SUI_ADDRESS_2": "0x2003e7b84de5efadbbf43f490012befb199d9a1ee1ef7cde751c54ac531c6478",
"CONTROLLER_AUTHSIG_2": {
"sig": "0x2f42bb580697adff64737ffcbd789d980da261e9bb5d0b7c333f50287394dc7234b380830735a6456d77fc91557aa5ad45e1eddff40e14b54ddf653185c7def01c",
"sig": "0x37f270ff7ecf31ee4e2a0a3bf7d2134f95c0a6ce9080aef42a2f2902a107e5850c7de43399a3f753e4a838624245ab64187ab47b1476ce4d60619b814145ed721b",
"derivedVia": "web3.eth.personal.sign",
"signedMessage": "localhost wants you to sign in with your Ethereum account:\n0xeF71c2604f17Ec6Fc13409DF24EfdC440D240d37\n\nTESTING TESTING 123\n\nURI: https://localhost/login\nVersion: 1\nChain ID: 1\nNonce: npiXq5HBli9qrnKVQ\nIssued At: 2023-10-03T14:32:12.975Z\nExpiration Time: 2215-05-30T14:32:12.975Z",
"signedMessage": "localhost wants you to sign in with your Ethereum account:\n0xeF71c2604f17Ec6Fc13409DF24EfdC440D240d37\n\nTESTING TESTING 123\n\nURI: https://localhost/login\nVersion: 1\nChain ID: 1\nNonce: W9sMGpyzyk924sYd0\nIssued At: 2023-11-07T16:21:15.152Z\nExpiration Time: 2215-07-04T16:21:15.152Z",
"address": "0xeF71c2604f17Ec6Fc13409DF24EfdC440D240d37"
}
}
}
26 changes: 21 additions & 5 deletions packages/lit-auth-client/src/lib/providers/BaseProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ import {
IRelay,
IRelayPKP,
IRelayRequestData,
MintRequestBody,
RelayClaimProcessor,
SessionSigs,
SignSessionKeyResponse,
} from '@lit-protocol/types';
import { ethers } from 'ethers';
import { validateMintRequestBody } from '../validators';

export abstract class BaseProvider {
/**
Expand Down Expand Up @@ -72,9 +74,14 @@ export abstract class BaseProvider {
*
* @returns {Promise<string>} - Mint transaction hash
*/
public async mintPKPThroughRelayer(authMethod: AuthMethod): Promise<string> {
public async mintPKPThroughRelayer(authMethod: AuthMethod, customArgs?: MintRequestBody): Promise<string> {
const data = await this.prepareRelayRequestData(authMethod);
const body = this.prepareMintBody(data);

if (customArgs && !validateMintRequestBody(customArgs)) {
throw new Error('Invalid mint request body');
};

const body = this.prepareMintBody(data, customArgs ?? {} as MintRequestBody);
const mintRes = await this.relay.mintPKP(body);
if (!mintRes || !mintRes.requestId) {
throw new Error('Missing mint response or request ID from relay server');
Expand Down Expand Up @@ -251,12 +258,15 @@ export abstract class BaseProvider {
* @param {number} data.authMethodType - Type of auth method
* @param {string} data.authMethodId - ID of auth method
* @param {string} [data.authMethodPubKey] - Public key associated with the auth method (used only in WebAuthn)
*
* @param {MintRequestBody} [customArgs] - Extra data to overwrite default params
*
* @returns {string} - Relay request body for minting PKP
*/
protected prepareMintBody(data: IRelayRequestData): string {
protected prepareMintBody(data: IRelayRequestData, customArgs: MintRequestBody): string {
const pubkey = data.authMethodPubKey || '0x';
const args = {

const defaultArgs: MintRequestBody = {
// default params
keyType: 2,
permittedAuthMethodTypes: [data.authMethodType],
permittedAuthMethodIds: [data.authMethodId],
Expand All @@ -265,6 +275,12 @@ export abstract class BaseProvider {
addPkpEthAddressAsPermittedAddress: true,
sendPkpToItself: true,
};

const args: MintRequestBody = {
...defaultArgs,
...customArgs,
};

const body = JSON.stringify(args);
return body;
}
Expand Down
106 changes: 106 additions & 0 deletions packages/lit-auth-client/src/lib/validators.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { validateMintRequestBody } from './validators';


describe('validateMintRequestBody', () => {
const mockConsoleError = jest.spyOn(console, 'error').mockImplementation();

afterEach(() => {
jest.clearAllMocks();
});

afterAll(() => {
jest.restoreAllMocks();
});

it('should pass validation when all fields are correct and present', () => {
const customArgs = {
keyType: 2,
permittedAuthMethodTypes: [1],
permittedAuthMethodIds: ['id123'],
permittedAuthMethodPubkeys: ['pubkey123'],
permittedAuthMethodScopes: [[1]],
addPkpEthAddressAsPermittedAddress: true,
sendPkpToItself: true,
};
expect(validateMintRequestBody(customArgs)).toBe(true);
expect(mockConsoleError).not.toHaveBeenCalled();
});

it('should pass validation when no fields are provided', () => {
const customArgs = {};
expect(validateMintRequestBody(customArgs)).toBe(true);
expect(mockConsoleError).not.toHaveBeenCalled();
});

it('should pass validation when some fields are provided and correct', () => {
const customArgs = {
keyType: 2,
permittedAuthMethodPubkeys: ['pubkey123'],
};
expect(validateMintRequestBody(customArgs)).toBe(true);
expect(mockConsoleError).not.toHaveBeenCalled();
});

it('should fail validation and log error for incorrect keyType', () => {
const customArgs = {
keyType: '2', // should be a number
};
expect(validateMintRequestBody(customArgs as any)).toBe(false);
expect(mockConsoleError).toHaveBeenCalledWith(expect.stringContaining('Invalid type for keyType'));
});

it('should fail validation and log error for incorrect permittedAuthMethodTypes', () => {
const customArgs = {
permittedAuthMethodTypes: ['1'], // should be an array of numbers
};
expect(validateMintRequestBody(customArgs as any)).toBe(false);
expect(mockConsoleError).toHaveBeenCalledWith(expect.stringContaining('Invalid type for permittedAuthMethodTypes'));
});

it('should fail validation and log error for incorrect permittedAuthMethodIds', () => {
const customArgs = {
permittedAuthMethodIds: [123], // should be an array of strings
};
expect(validateMintRequestBody(customArgs as any)).toBe(false);
expect(mockConsoleError).toHaveBeenCalledWith(expect.stringContaining('Invalid type for permittedAuthMethodIds'));
});

it('should fail validation and log error for incorrect permittedAuthMethodPubkeys', () => {
const customArgs = {
permittedAuthMethodPubkeys: [123], // should be an array of strings
};
expect(validateMintRequestBody(customArgs as any)).toBe(false);
expect(mockConsoleError).toHaveBeenCalledWith(expect.stringContaining('Invalid type for permittedAuthMethodPubkeys'));
});
it('should fail validation and log error for incorrect permittedAuthMethodScopes', () => {
const customArgs = {
permittedAuthMethodScopes: [[1]], // should be an array of ethers.BigNumber
};
expect(validateMintRequestBody(customArgs as any)).toBe(true);
});

it('should fail validation and log error for incorrect addPkpEthAddressAsPermittedAddress', () => {
const customArgs = {
addPkpEthAddressAsPermittedAddress: 'true', // should be a boolean
};
expect(validateMintRequestBody(customArgs as any)).toBe(false);
expect(mockConsoleError).toHaveBeenCalledWith(expect.stringContaining('Invalid type for addPkpEthAddressAsPermittedAddress'));
});

it('should fail validation and log error for incorrect sendPkpToItself', () => {
const customArgs = {
sendPkpToItself: 'true', // should be a boolean
};
expect(validateMintRequestBody(customArgs as any)).toBe(false);
expect(mockConsoleError).toHaveBeenCalledWith(expect.stringContaining('Invalid type for sendPkpToItself'));
});

it('should fail validation and log error for extraneous keys', () => {
const customArgs = {
extraneousKey: 'unexpected', // This key is not defined in MintRequestBody
};
expect(validateMintRequestBody(customArgs as any)).toBe(false);
expect(mockConsoleError).toHaveBeenCalledWith(expect.stringContaining('Invalid key found: extraneousKey'));
});

});
51 changes: 51 additions & 0 deletions packages/lit-auth-client/src/lib/validators.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { MintRequestBody } from "@lit-protocol/types";

export const validateMintRequestBody = (customArgs: Partial<MintRequestBody>): boolean => {
let isValid = true;
const validKeys = ['keyType', 'permittedAuthMethodTypes', 'permittedAuthMethodIds', 'permittedAuthMethodPubkeys', 'permittedAuthMethodScopes', 'addPkpEthAddressAsPermittedAddress', 'sendPkpToItself'];

// Check for any extraneous keys
for (const key of Object.keys(customArgs)) {
if (!validKeys.includes(key)) {
console.error(`Invalid key found: ${key}. This key is not allowed. Valid keys are: ${validKeys.join(', ')}`);
isValid = false;
}
}

if (customArgs.keyType !== undefined && typeof customArgs.keyType !== 'number') {
console.error('Invalid type for keyType: expected a number.');
isValid = false;
}

if (customArgs.permittedAuthMethodTypes !== undefined && (!Array.isArray(customArgs.permittedAuthMethodTypes) || !customArgs.permittedAuthMethodTypes.every(type => typeof type === 'number'))) {
console.error('Invalid type for permittedAuthMethodTypes: expected an array of numbers.');
isValid = false;
}

if (customArgs.permittedAuthMethodIds !== undefined && (!Array.isArray(customArgs.permittedAuthMethodIds) || !customArgs.permittedAuthMethodIds.every(id => typeof id === 'string'))) {
console.error('Invalid type for permittedAuthMethodIds: expected an array of strings.');
isValid = false;
}

if (customArgs.permittedAuthMethodPubkeys !== undefined && (!Array.isArray(customArgs.permittedAuthMethodPubkeys) || !customArgs.permittedAuthMethodPubkeys.every(pubkey => typeof pubkey === 'string'))) {
console.error('Invalid type for permittedAuthMethodPubkeys: expected an array of strings.');
isValid = false;
}

if (customArgs.permittedAuthMethodScopes !== undefined && (!Array.isArray(customArgs.permittedAuthMethodScopes) || !customArgs.permittedAuthMethodScopes.every(scope => Array.isArray(scope) && scope.every(s => typeof s === 'number')))) {
console.error('Invalid type for permittedAuthMethodScopes: expected an array of arrays of numberr.');
isValid = false;
}

if (customArgs.addPkpEthAddressAsPermittedAddress !== undefined && typeof customArgs.addPkpEthAddressAsPermittedAddress !== 'boolean') {
console.error('Invalid type for addPkpEthAddressAsPermittedAddress: expected a boolean.');
isValid = false;
}

if (customArgs.sendPkpToItself !== undefined && typeof customArgs.sendPkpToItself !== 'boolean') {
console.error('Invalid type for sendPkpToItself: expected a boolean.');
isValid = false;
}

return isValid;
};
16 changes: 13 additions & 3 deletions packages/types/src/lib/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -566,7 +566,7 @@ export interface ExecuteJsResponse {
};
}

export interface LitNodePromise {}
export interface LitNodePromise { }

export interface SendNodeCommand {
url: string;
Expand Down Expand Up @@ -1122,7 +1122,7 @@ export interface RPCUrls {
btc?: string;
}

export interface PKPEthersWalletProp extends PKPBaseProp {}
export interface PKPEthersWalletProp extends PKPBaseProp { }

export interface PKPCosmosWalletProp extends PKPBaseProp {
addressPrefix: string | 'cosmos'; // bech32 address prefix (human readable part) (default: cosmos)
Expand Down Expand Up @@ -1255,6 +1255,16 @@ export interface LitRelayConfig {
relayApiKey?: string;
}

export interface MintRequestBody {
keyType: number;
permittedAuthMethodTypes: number[];
permittedAuthMethodIds: string[];
permittedAuthMethodPubkeys: string[];
permittedAuthMethodScopes: any[][] // ethers.BigNumber;
addPkpEthAddressAsPermittedAddress: boolean;
sendPkpToItself: boolean;
};

export interface IRelayRequestData {
/**
* Type of auth method
Expand Down Expand Up @@ -1483,7 +1493,7 @@ export interface LoginUrlParams {
error: string | null;
}

export interface BaseAuthenticateOptions {}
export interface BaseAuthenticateOptions { }

export interface EthWalletAuthenticateOptions extends BaseAuthenticateOptions {
/**
Expand Down
Loading