Skip to content

Commit

Permalink
feat: allowlist module installation and uninstallation
Browse files Browse the repository at this point in the history
  • Loading branch information
Zer0dot committed Dec 17, 2024
1 parent 74e34e6 commit 57f79ec
Show file tree
Hide file tree
Showing 4 changed files with 192 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
type Transport,
encodeFunctionData,
concatHex,
zeroAddress,
} from "viem";

import { semiModularAccountBytecodeAbi } from "../../abis/semiModularAccountBytecodeAbi.js";
Expand Down Expand Up @@ -95,7 +96,9 @@ export const installValidationActions: <
}

if (validationConfig.entityId === 0) {
throw new EntityIdOverrideError();
if (validationConfig.moduleAddress !== zeroAddress) {
throw new EntityIdOverrideError();
}
}

const callData = encodeFunctionData({
Expand Down
96 changes: 87 additions & 9 deletions account-kit/smart-contracts/src/ma-v2/client/client.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { custom, parseEther, publicActions } from "viem";
import { custom, parseEther, publicActions, zeroAddress } from "viem";

import { LocalAccountSigner, type SmartAccountSigner } from "@aa-sdk/core";

Expand All @@ -10,6 +10,8 @@ import { accounts } from "~test/constants.js";
import { installValidationActions } from "../actions/install-validation/installValidation.js";
import { addresses } from "../utils.js";
import { SingleSignerValidationModule } from "../modules/single-signer-validation/module.js";
import { allowlistModule } from "../modules/allowlist-module/module.js";
import { HookType } from "../actions/common/types.js";

describe("MA v2 Tests", async () => {
const instance = local070Instance;
Expand All @@ -30,8 +32,8 @@ describe("MA v2 Tests", async () => {
const target = "0x000000000000000000000000000000000000dEaD";
const sendAmount = parseEther("1");

const getTargetBalance = async (): Promise<number> => {
return client.getBalance({
const getTargetBalance = async (): Promise<bigint> => {
return (client as any).getBalance({
address: target,
});
};
Expand Down Expand Up @@ -169,15 +171,91 @@ describe("MA v2 Tests", async () => {
isGlobalValidation: true,
});

result = sessionKeyClient.sendUserOperation({
uo: {
target: target,
value: sendAmount,
data: "0x",
await expect(
sessionKeyClient.sendUserOperation({
uo: {
target: target,
value: sendAmount,
data: "0x",
},
})
).rejects.toThrowError();
});

it("installs allowlist module, then uninstalls", async () => {
let provider = (await givenConnectedProvider({ signer })).extend(
installValidationActions
);

await setBalance(client, {
address: provider.getAddress(),
value: parseEther("2"),
});

const hookInstallData = allowlistModule.encodeOnInstallData({
entityId: 1,
inputs: [
{
target,
hasSelectorAllowlist: false,
hasERC20SpendLimit: false,
erc20SpendLimit: 0n,
selectors: [],
},
],
});

const installResult = await provider.installValidation({
validationConfig: {
moduleAddress: zeroAddress,
entityId: 0,
isGlobal: true,
isSignatureValidation: true,
isUserOpValidation: true,
},
selectors: [],
installData: "0x",
hooks: [
{
hookConfig: {
address: addresses.allowlistModule,
entityId: 0, // uint32
hookType: HookType.VALIDATION,
hasPreHooks: true,
hasPostHooks: true,
},
initData: hookInstallData,
},
],
});

await expect(
provider.waitForUserOperationTransaction(installResult)
).resolves.not.toThrowError();

const hookUninstallData = allowlistModule.encodeOnUninstallData({
entityId: 0,
inputs: [
{
target,
hasSelectorAllowlist: false,
hasERC20SpendLimit: false,
erc20SpendLimit: 0n,
selectors: [],
},
],
});

const uninstallResult = await provider.uninstallValidation({
moduleAddress: zeroAddress,
entityId: 0,
uninstallData: "0x",
hookUninstallDatas: [hookUninstallData],
});

await expect(result).rejects.toThrowError();
await expect(
provider.waitForUserOperationTransaction(uninstallResult)
).resolves.not.toThrowError();
});

const givenConnectedProvider = async ({
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import { encodeAbiParameters, type Address, type Hex } from "viem";

import { allowlistModuleAbi } from "./abis/allowlistModuleAbi.js";

const addresses: Record<number | "default", Address> = {
default: "0xE46ca4a98c485caEE2Abb6ef5116292B8c78a868",
};

const meta = {
name: "AllowlistModule",
version: "alpha.1",
addresses,
};

export const allowlistModule = {
meta,
abi: allowlistModuleAbi,
encodeOnInstallData: (args: {
entityId: number;
inputs: Array<{
target: Address;
hasSelectorAllowlist: boolean;
hasERC20SpendLimit: boolean;
erc20SpendLimit: bigint;
selectors: Array<Hex>;
}>;
}): Hex => {
const { entityId, inputs } = args;
return encodeAbiParameters(
[
{ type: "uint32" },
{
type: "tuple[]",
components: [
{ type: "address" },
{ type: "bool" },
{ type: "bool" },
{ type: "uint256" },
{ type: "bytes4[]" },
],
},
],
[
entityId,
inputs.map(
(input) =>
[
input.target,
input.hasSelectorAllowlist,
input.hasERC20SpendLimit,
input.erc20SpendLimit,
input.selectors,
] as const
),
]
);
},

encodeOnUninstallData: (args: {
entityId: number;
inputs: Array<{
target: Address;
hasSelectorAllowlist: boolean;
hasERC20SpendLimit: boolean;
erc20SpendLimit: bigint;
selectors: Array<Hex>;
}>;
}): Hex => {
const { entityId, inputs } = args;
return encodeAbiParameters(
[
{ type: "uint32" },
{
type: "tuple[]",
components: [
{ type: "address" },
{ type: "bool" },
{ type: "bool" },
{ type: "uint256" },
{ type: "bytes4[]" },
],
},
],
[
entityId,
inputs.map(
(input) =>
[
input.target,
input.hasSelectorAllowlist,
input.hasERC20SpendLimit,
input.erc20SpendLimit,
input.selectors,
] as const
),
]
);
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { encodeAbiParameters, type Address, type Hex } from "viem";

import { singleSignerValidationModuleAbi } from "./abis/singleSignerValidationModuleAbi.js";

const addresses = {
const addresses: Record<number | "default", Address> = {
default: "0xEa3a0b544d517f6Ed3Dc2186C74D869c702C376e",
} as Record<number | "default", Address>;
};

const meta = {
name: "SingleSignerValidation",
Expand Down

0 comments on commit 57f79ec

Please sign in to comment.