Skip to content

Commit

Permalink
fix: lost changes from other PRs (#1259)
Browse files Browse the repository at this point in the history
  • Loading branch information
howydev authored Jan 3, 2025
1 parent e513d84 commit 6546664
Show file tree
Hide file tree
Showing 26 changed files with 972 additions and 57 deletions.
8 changes: 4 additions & 4 deletions aa-sdk/core/src/errors/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,9 @@ export class InvalidNonceKeyError extends BaseError {
* @param {bigint} nonceKey the invalid nonceKey used
*/
constructor(nonceKey: bigint) {
super(`Nonce key is ${nonceKey} but has to be less than 2**152`);
super(
`Nonce key is ${nonceKey} but has to be less than or equal to 2**152`
);
}
}

Expand All @@ -98,8 +100,6 @@ export class EntityIdOverrideError extends BaseError {
* Initializes a new instance of the error message with a default message indicating that the nonce key is invalid.
*/
constructor() {
super(
`Installing entityId of 0 overrides the owner's entity id in the account`
);
super(`EntityId of 0 is reserved for the owner and cannot be used`);
}
}
48 changes: 48 additions & 0 deletions account-kit/smart-contracts/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,51 @@ export {
getMAInitializationData,
getMSCAUpgradeToData,
} from "./msca/utils.js";

// ma v2 exports
export { accountFactoryAbi } from "./ma-v2/abis/accountFactoryAbi.js";
export { modularAccountAbi } from "./ma-v2/abis/modularAccountAbi.js";
export { semiModularAccountBytecodeAbi } from "./ma-v2/abis/semiModularAccountBytecodeAbi.js";
export { semiModularAccountStorageAbi } from "./ma-v2/abis/semiModularAccountStorageAbi.js";

export { nativeSMASigner } from "./ma-v2/account/nativeSMASigner.js";
export type * from "./ma-v2/account/semiModularAccountV2.js";
export { createSMAV2Account } from "./ma-v2/account/semiModularAccountV2.js";

export type {
ModuleEntity,
ValidationConfig,
HookConfig,
ValidationData,
} from "./ma-v2/actions/common/types.js";
export { HookType } from "./ma-v2/actions/common/types.js";
export {
serializeValidationConfig,
serializeHookConfig,
serializeModuleEntity,
} from "./ma-v2/actions/common/utils.js";
export type * from "./ma-v2/actions/install-validation/installValidation.js";
export { installValidationActions } from "./ma-v2/actions/install-validation/installValidation.js";

export type * from "./ma-v2/client/client.js";
export { createSMAV2AccountClient } from "./ma-v2/client/client.js";

export {
getDefaultAllowlistModuleAddress,
getDefaultNativeTokenLimitModuleAddress,
getDefaultPaymasterGuardModuleAddress,
getDefaultSingleSignerValidationModuleAddress,
getDefaultTimeRangeModuleAddress,
getDefaultWebauthnValidationModuleAddress,
} from "./ma-v2/modules/utils.js";
export { allowlistModuleAbi } from "./ma-v2/modules/allowlist-module/abis/allowlistModuleAbi.js";
export { AllowlistModule } from "./ma-v2/modules/allowlist-module/module.js";
export { nativeTokenLimitModuleAbi } from "./ma-v2/modules/native-token-limit-module/abis/nativeTokenLimitModuleAbi.js";
export { NativeTokenLimitModule } from "./ma-v2/modules/native-token-limit-module/module.js";
export { paymasterGuardModuleAbi } from "./ma-v2/modules/paymaster-guard-module/abis/paymasterGuardModuleAbi.js";
export { PaymasterGuardModule } from "./ma-v2/modules/paymaster-guard-module/module.js";
export { singleSignerValidationModuleAbi } from "./ma-v2/modules/single-signer-validation/abis/singleSignerValidationModuleAbi.js";
export { SingleSignerValidationModule } from "./ma-v2/modules/single-signer-validation/module.js";
export { timeRangeModuleAbi } from "./ma-v2/modules/time-range-module/abis/timeRangeModuleAbi.js";
export { TimeRangeModule } from "./ma-v2/modules/time-range-module/module.js";
export { webauthnValidationModuleAbi } from "./ma-v2/modules/webauthn-validation/abis/webauthnValidationAbi.js";
18 changes: 10 additions & 8 deletions account-kit/smart-contracts/src/ma-v2/account/nativeSMASigner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,17 @@ import {
type Address,
} from "viem";

import { packUOSignature, pack1271Signature } from "../utils.js";
import {
packUOSignature,
pack1271Signature,
DEFAULT_OWNER_ENTITY_ID,
} from "../utils.js";
/**
* Creates an object with methods for generating a dummy signature, signing user operation hashes, signing messages, and signing typed data.
*
* @example
* ```ts
* import { singleSignerMessageSigner } from "@account-kit/smart-contracts";
* import { nativeSMASigner } from "@account-kit/smart-contracts";
* import { LocalAccountSigner } from "@aa-sdk/core";
*
Expand All @@ -26,20 +30,18 @@ import { packUOSignature, pack1271Signature } from "../utils.js";
*
* const signer = LocalAccountSigner.mnemonicToAccountSigner(MNEMONIC);
*
* const messageSigner = singleSignerMessageSigner(signer, chain);
* const messageSigner = nativeSMASigner(signer, chain, account.address);
* ```
*
* @param {SmartAccountSigner} signer Signer to use for signing operations
* @param {Chain} chain Chain object for the signer
* @param {Address} accountAddress address of the smart account using this signer
* @param {number} entityId the entity id of the signing validation
* @returns {object} an object with methods for signing operations and managing signatures
*/
export const nativeSMASigner = (
signer: SmartAccountSigner,
chain: Chain,
accountAddress: Address,
entityId: number
accountAddress: Address
) => {
return {
getDummySignature: (): Hex => {
Expand Down Expand Up @@ -79,7 +81,7 @@ export const nativeSMASigner = (
},
primaryType: "ReplaySafeHash",
}),
entityId,
entityId: DEFAULT_OWNER_ENTITY_ID,
});
},

Expand Down Expand Up @@ -112,7 +114,7 @@ export const nativeSMASigner = (
},
primaryType: "ReplaySafeHash",
}),
entityId,
entityId: DEFAULT_OWNER_ENTITY_ID,
});
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ export type ValidationDataParams =
entityId: number;
};

export type SMAV2Account<
export type MAV2Account<
TSigner extends SmartAccountSigner = SmartAccountSigner
> = SmartContractAccountWithSigner<"SMAV2Account", TSigner, "0.7.0"> & {
> = SmartContractAccountWithSigner<"MAV2Account", TSigner, "0.7.0"> & {
signerEntity: SignerEntity;
getExecutionData: (selector: Hex) => Promise<ExecutionDataView>;
getValidationData: (
Expand All @@ -81,7 +81,7 @@ export type CreateSMAV2AccountParams<
TTransport extends Transport = Transport,
TSigner extends SmartAccountSigner = SmartAccountSigner
> = Pick<
ToSmartContractAccountParams<"SMAV2Account", TTransport, Chain, "0.7.0">,
ToSmartContractAccountParams<"MAV2Account", TTransport, Chain, "0.7.0">,
"transport" | "chain" | "accountAddress"
> & {
signer: TSigner;
Expand All @@ -98,11 +98,18 @@ export async function createSMAV2Account<
TSigner extends SmartAccountSigner = SmartAccountSigner
>(
config: CreateSMAV2AccountParams<TTransport, TSigner>
): Promise<SMAV2Account<TSigner>>;
): Promise<MAV2Account<TSigner>>;

/**
* Creates an SMAV2 account using defined parameters including chain, signer, salt, factory address, and more.
* Handles account initialization code, nonce generation, transaction encoding, and more to construct a modular account with optional validation hooks.
*
* @param {CreateSMAV2AccountParams} config Configuration parameters for creating an SMAV2 account. Includes chain details, signer, salt, factory address, and more.
* @returns {Promise<MAV2Account>} A promise that resolves to an `MAV2Account` providing methods for nonce retrieval, transaction execution, and more.
*/
export async function createSMAV2Account(
config: CreateSMAV2AccountParams
): Promise<SMAV2Account> {
): Promise<MAV2Account> {
const {
transport,
chain,
Expand All @@ -117,10 +124,12 @@ export async function createSMAV2Account(
isGlobalValidation: true,
entityId: DEFAULT_OWNER_ENTITY_ID,
},
signerEntity: {
isGlobalValidation = true,
entityId = DEFAULT_OWNER_ENTITY_ID,
} = {},
} = config;

const { isGlobalValidation, entityId } = signerEntity;

if (entityId > Number(maxUint32)) {
throw new InvalidEntityIdError(entityId);
}
Expand Down Expand Up @@ -188,18 +197,18 @@ export async function createSMAV2Account(
chain,
entryPoint,
accountAddress: _accountAddress,
source: `SMAV2Account`,
source: `MAV2Account`,
encodeExecute,
encodeBatchExecute,
getAccountInitCode,
...(entityId === DEFAULT_OWNER_ENTITY_ID
? nativeSMASigner(signer, chain, _accountAddress, entityId)
? nativeSMASigner(signer, chain, _accountAddress)
: singleSignerMessageSigner(signer, chain, _accountAddress, entityId)),
});

// TODO: add deferred action flag
const getAccountNonce = async (nonceKey?: bigint): Promise<bigint> => {
if (nonceKey && nonceKey > maxUint152) {
const getAccountNonce = async (nonceKey: bigint = 0n): Promise<bigint> => {
if (nonceKey > maxUint152) {
throw new InvalidNonceKeyError(nonceKey);
}

Expand All @@ -210,7 +219,7 @@ export async function createSMAV2Account(
});

const fullNonceKey: bigint =
(nonceKey ? nonceKey << 40n : 0n) +
(nonceKey << 40n) +
BigInt(entityId << 8) +
(isGlobalValidation ? 1n : 0n);

Expand Down
71 changes: 71 additions & 0 deletions account-kit/smart-contracts/src/ma-v2/actions/common/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,31 @@ import { type Hex, toHex, concatHex } from "viem";
import type { ValidationConfig, HookConfig, ModuleEntity } from "./types";
import { HookType } from "./types.js";

/**
* Serializes a validation configuration into a hexadecimal string representation. This involves converting boolean flags into bitwise representation and combining them with serialized module entity data.
*
* @example
* ```ts
* import { serializeValidationConfig } from "@account-kit/smart-contracts";
* import { Address } from "viem";
*
* const moduleAddress: Address = "0x1234";
* const entityId: number = 1234;
* const isGlobal: boolean = true;
* const isSignatureValidation: boolean = false;
* const isUserOpValidation: boolean = true;
*
* const validationConfigHex = serializeValidationConfig({
* moduleAddress,
* entityId
* isGlobal,
* isSignatureValidation,
* isUserOpValidation
* });
* ```
* @param {ValidationConfig} config The validation configuration object containing details to serialize
* @returns {Hex} A hexadecimal string representing the serialized configuration
*/
export function serializeValidationConfig(config: ValidationConfig): Hex {
const isUserOpValidationBit = config.isUserOpValidation ? 1 : 0;
const isSignatureValidationBit = config.isSignatureValidation ? 2 : 0;
Expand All @@ -14,6 +39,32 @@ export function serializeValidationConfig(config: ValidationConfig): Hex {
]);
}

/**
* Serializes a `HookConfig` object into a `Hex` format by encoding the hook type, presence of post/pre hooks, address, and entity ID.
*
* @example
* ```ts
* import { type HookType, serializeHookConfig } from "@account-kit/smart-contracts";
* import { Address } from "viem";
*
* const moduleAddress: Address = "0x1234";
* const entityId: number = 1234;
* const hookType: HookType = HookType.Validation;
* const hasPostHooks: boolean = false;
* const hasPreHooks: boolean = true;
*
* const hookConfigHex = serializeHookConfig({
* moduleAddress,
* entityId
* hookType,
* hasPostHooks,
* hasPreHooks
* });
* ```
*
* @param {HookConfig} config The hook configuration containing address, entity ID, hook type, and post/pre hook indicators
* @returns {Hex} The serialized hook configuration in hexadecimal format
*/
export function serializeHookConfig(config: HookConfig): Hex {
const hookTypeBit = config.hookType === HookType.VALIDATION ? 1 : 0;
const hasPostHooksBit = config.hasPostHooks ? 2 : 0;
Expand All @@ -27,6 +78,26 @@ export function serializeHookConfig(config: HookConfig): Hex {
]);
}

/**
* Serializes a module entity into a hexadecimal format by concatenating the module address and entity ID.
*
* @example
* ```ts
* import { serializeModuleEntity } from "@account-kit/smart-contracts";
* import { Address } from "viem";
*
* const moduleAddress: Address = "0x1234";
* const entityId: number = 1234;
*
* const moduleEntityHex = serializeModuleEntity({
* moduleAddress,
* entityId
* });
* ```
*
* @param {ModuleEntity} config The module entity configuration containing the module address and entity ID
* @returns {Hex} A hexadecimal string representation of the serialized module entity
*/
export function serializeModuleEntity(config: ModuleEntity): Hex {
return concatHex([config.moduleAddress, toHex(config.entityId, { size: 4 })]);
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {
} from "../common/utils.js";

import { type SMAV2AccountClient } from "../../client/client.js";
import { type SMAV2Account } from "../../account/semiModularAccountV2.js";
import { type MAV2Account } from "../../account/semiModularAccountV2.js";
import { DEFAULT_OWNER_ENTITY_ID } from "../../utils.js";

export type InstallValidationParams<
Expand All @@ -38,9 +38,9 @@ export type InstallValidationParams<
hookConfig: HookConfig;
initData: Hex;
}[];
account?: SMAV2Account<TSigner> | undefined;
account?: MAV2Account<TSigner> | undefined;
} & UserOperationOverridesParameter<
GetEntryPointFromAccount<SMAV2Account<TSigner>>
GetEntryPointFromAccount<MAV2Account<TSigner>>
>;

export type UninstallValidationParams<
Expand All @@ -50,9 +50,9 @@ export type UninstallValidationParams<
entityId: number;
uninstallData: Hex;
hookUninstallDatas: Hex[];
account?: SMAV2Account<TSigner> | undefined;
account?: MAV2Account<TSigner> | undefined;
} & UserOperationOverridesParameter<
GetEntryPointFromAccount<SMAV2Account<TSigner>>
GetEntryPointFromAccount<MAV2Account<TSigner>>
>;

export type InstallValidationActions<
Expand All @@ -66,6 +66,50 @@ export type InstallValidationActions<
) => Promise<SendUserOperationResult>;
};

/**
* Provides validation installation and uninstallation functionalities for a MA v2 client, ensuring compatibility with `SmartAccountClient`.
*
* @example
* ```ts
* import { createSMAV2AccountClient, installValidationActions, getDefaultSingleSignerValidationModuleAddress, SingleSignerValidationModule } from "@account-kit/smart-contracts";
* import { Address } from "viem";
*
* const client = (await createSMAV2AccountClient({ ... })).extend(installValidationActions);
* const sessionKeyAddress: Address = "0x1234";
* const sessionKeyEntityId: number = 1;
*
* await client.installValidation({
* validationConfig: {
* moduleAddress: getDefaultSingleSignerValidationModuleAddress(
* client.chain
* ),
* entityId: sessionKeyEntityId,
* isGlobal: true,
* isSignatureValidation: false,
* isUserOpValidation: true,
* },
* selectors: [],
* installData: SingleSignerValidationModule.encodeOnInstallData({
* entityId: sessionKeyEntityId,
* signer: sessionKeyAddress,
* }),
* hooks: [],
* });
*
* await client.uninstallValidation({
* moduleAddress: sessionKeyAddress,
* entityId: sessionKeyEntityId,
* uninstallData: SingleSignerValidationModule.encodeOnUninstallData({
* entityId: sessionKeyEntityId,
* }),
* hookUninstallDatas: [],
* });
*
* ```
*
* @param {object} client - The client instance which provides account and sendUserOperation functionality.
* @returns {object} - An object containing two methods, `installValidation` and `uninstallValidation`.
*/
export const installValidationActions: <
TSigner extends SmartAccountSigner = SmartAccountSigner
>(
Expand Down
Loading

0 comments on commit 6546664

Please sign in to comment.