@locker-labs/sdk
Version:
A utility library for enhancing your ERC-4337 experience
85 lines (71 loc) • 2.42 kB
text/typescript
import { alchemy } from "@account-kit/infra";
import { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";
import type { ILockerClientParams, ILockerClient } from "./types.js";
import { adaptLockerChain2AlchemyChain } from "./helpers.js";
/**
* Validates the input parameters for creating the client.
*/
function validateClientParams(params: ILockerClientParams): void {
if (!params.alchemyApiKey || params.alchemyApiKey.trim() === "") {
throw new Error(
"Invalid parameter: 'apiKey' is required and cannot be empty."
);
}
if (!params.chain) {
throw new Error("Invalid parameter: 'chain' is required.");
}
if (!params.signer) {
throw new Error(
"Invalid configuration: No signer provided and no default PRIVATE KEY found in environment."
);
}
}
/**
* Creates a locker modular account client without any plugins.
* Users can later install plugins onto this client using installPlugin.
*
* @param params - The configuration parameters for creating the client.
* @returns A promise that resolves to the locker modular account client.
*/
export async function createLockerClient(
params: ILockerClientParams
): Promise<ILockerClient> {
validateClientParams(params);
const { alchemyApiKey: apiKey, chain: lockerChain, signer, salt } = params;
const chain = adaptLockerChain2AlchemyChain(lockerChain);
const aaClient = await createModularAccountAlchemyClient({
salt: salt ? salt : BigInt(0),
signer,
chain,
transport: alchemy({ apiKey }),
});
const lockerClient: ILockerClient = {
getAddress: () => aaClient.getAddress(),
isPluginInstalled: async (plugin) => {
const installedPlugins = await aaClient.getInstalledPlugins({});
if (!installedPlugins.includes(plugin)) {
return false;
}
return true;
},
extend: (pluginActions) => aaClient.extend(pluginActions) as ILockerClient,
installPlugin: async (plugin) => {
return await aaClient.installPlugin({
pluginAddress: plugin,
});
},
uninstallPlugin: async (plugin) => {
return await aaClient.uninstallPlugin({ pluginAddress: plugin });
},
sendUserOps: async (to, data, value) => {
return await aaClient.sendUserOperation({
uo: {
target: to,
data,
value,
},
});
},
};
return lockerClient as ILockerClient;
}