Skip to content

Commit

Permalink
Chore(SMA-604): ecdsa tests (#418)
Browse files Browse the repository at this point in the history
* Resolved SMA-604

* Update module types for jsdoc

* ts fix

* types fix

* yarn lock

* PR comments

* typos
  • Loading branch information
joepegler committed Feb 22, 2024
1 parent 00ad1da commit 1a8f296
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 8 deletions.
5 changes: 5 additions & 0 deletions packages/account/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ export {
DEFAULT_SESSION_KEY_MANAGER_MODULE,
DEFAULT_MULTICHAIN_MODULE,
DEFAULT_BATCHED_SESSION_ROUTER_MODULE,
type ECDSAOwnershipValidationModuleConfig,
type BatchedSessionRouterModuleConfig,
type SessionKeyManagerModuleConfig,
type MultiChainValidationModuleConfig,
type SessionValidationModuleConfig,
} from "@biconomy/modules";

export const createSmartAccountClient = BiconomySmartAccountV2.create;
Expand Down
2 changes: 1 addition & 1 deletion packages/account/src/utils/Types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export type BiconomyFactoriesByVersion = Record<string, string>;
export type BiconomyImplementationsByVersion = Record<string, string>;

export type SmartAccountConfig = {
/** entryPointAddress: address of the smart account factory */
/** entryPointAddress: address of the entry point */
entryPointAddress: string;
/** factoryAddress: address of the smart account factory */
bundler?: IBundler;
Expand Down
1 change: 1 addition & 0 deletions packages/bundler/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
## 4.0.0 (2023-07-02)

Export createBundler alias for static Bundler.create call
Abstract away chainId: [0fefb35](https://github.com/bcnmy/biconomy-client-sdk/pull/375/commits/0fefb358e3927d7b026774a785d3711e80f1049a)

## 3.1.3 (2023-12-28)

Expand Down
1 change: 0 additions & 1 deletion packages/modules/src/BatchedSessionRouterModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ export class BatchedSessionRouterModule extends BaseValidationModule {
const sessionModule = await SessionKeyManagerModule.create({
moduleAddress: instance.sessionManagerModuleAddress,
smartAccountAddress: moduleConfig.smartAccountAddress,
nodeClientUrl: moduleConfig.nodeClientUrl,
storageType: moduleConfig.storageType,
});

Expand Down
50 changes: 44 additions & 6 deletions packages/modules/src/utils/Types.ts
Original file line number Diff line number Diff line change
@@ -1,44 +1,56 @@
import { Chain, Hex } from "viem";
import { UserOperationStruct, SmartAccountSigner } from "@alchemy/aa-core";
import { SmartAccountSigner, UserOperationStruct } from "@alchemy/aa-core";
import { SessionKeyManagerModule } from "../SessionKeyManagerModule";
import { ISessionStorage } from "../interfaces/ISessionStorage.js";
import { SupportedSigner } from "@biconomy/common";
export type ModuleVersion = "V1_0_0"; // | 'V1_0_1'

export interface BaseValidationModuleConfig {
/** entryPointAddress: address of the entry point */
entryPointAddress?: Hex;
}

export interface ECDSAOwnershipValidationModuleConfig extends BaseValidationModuleConfig {
/** Address of the module */
moduleAddress?: Hex;
/** Version of the module */
version?: ModuleVersion;
/** Signer: viemWallet or ethers signer. Ingested when passed into smartAccount */
signer: SupportedSigner;
}

export interface ECDSAOwnershipValidationModuleConfigConstructorProps extends BaseValidationModuleConfig {
/** Address of the module */
moduleAddress?: Hex;
/** Version of the module */
version?: ModuleVersion;
/** Signer: Converted from viemWallet or ethers signer to SmartAccountSigner */
signer: SmartAccountSigner;
}

export interface SessionKeyManagerModuleConfig extends BaseValidationModuleConfig {
/** Address of the module */
moduleAddress?: Hex;
/** Version of the module */
version?: ModuleVersion;
nodeClientUrl?: string;
/** SmartAccount address */
smartAccountAddress: string;
storageType?: StorageType;
sessionStorageClient?: ISessionStorage;
}

export interface BatchedSessionRouterModuleConfig extends BaseValidationModuleConfig {
/** Address of the module */
moduleAddress?: Hex;
/** Version of the module */
version?: ModuleVersion;

sessionKeyManagerModule?: SessionKeyManagerModule; // could be BaseValidationModule

/** Session Key Manager module: Could be BaseValidationModule */
sessionKeyManagerModule?: SessionKeyManagerModule;
/** Session Key Manager module address */
sessionManagerModuleAddress?: Hex;
nodeClientUrl?: string;
/** Address of the associated smart account */
smartAccountAddress: string;
/** Storage type, e.g. local storage */
storageType?: StorageType;
}

Expand All @@ -47,31 +59,42 @@ export enum StorageType {
}

export type SessionParams = {
/** Redundant now as we've favoured uuid() */
sessionID?: string;
/** Session Signer: viemWallet or ethers signer. Ingested when passed into smartAccount */
sessionSigner: SupportedSigner;
/** The session validation module is a sub-module smart-contract which works with session key manager validation module. It validates the userop calldata against the defined session permissions (session key data) within the contract. */
sessionValidationModule?: Hex;
/** Additional info if needed to be appended in signature */
additionalSessionData?: string;
};

export type ModuleInfo = {
// Could be a full object of below params and that way it can be an array too!
// sessionParams?: SessionParams[] // where SessionParams is below four
sessionID?: string;
/** Session Signer: viemWallet or ethers signer. Ingested when passed into smartAccount */
sessionSigner?: SupportedSigner;
/** The session validation module is a sub-module smart-contract which works with session key manager validation module. It validates the userop calldata against the defined session permissions (session key data) within the contract. */
sessionValidationModule?: Hex;
/** Additional info if needed to be appended in signature */
additionalSessionData?: string;
batchSessionParams?: SessionParams[];
};

export interface SendUserOpParams extends ModuleInfo {
/** "validation_and_execution" is recommended during development for improved debugging & devEx, but will add some additional latency to calls. "validation" can be used in production ro remove this latency once flows have been tested. */
simulationType?: SimulationType;
}

export type SimulationType = "validation" | "validation_and_execution";

export type SignerData = {
/** Public key */
pbKey: string;
/** Private key */
pvKey: `0x${string}`;
/** Network Id */
chainId?: Chain;
};

Expand All @@ -81,27 +104,38 @@ export type CreateSessionDataResponse = {
};

export interface CreateSessionDataParams {
/** window end for the session key */
validUntil: number;
/** window start for the session key */
validAfter: number;
sessionValidationModule: Hex;
sessionPublicKey: Hex;
sessionKeyData: Hex;
/** we generate uuid based sessionId. but if you prefer to track it on your side and attach custom session identifier this can be passed */
preferredSessionId?: string;
}

export interface MultiChainValidationModuleConfig extends BaseValidationModuleConfig {
/** Address of the module */
moduleAddress?: Hex;
/** Version of the module */
version?: ModuleVersion;
/** Signer: viemWallet or ethers signer. Ingested when passed into smartAccount */
signer: SupportedSigner;
}
export interface MultiChainValidationModuleConfigConstructorProps extends BaseValidationModuleConfig {
/** Address of the module */
moduleAddress?: Hex;
/** Version of the module */
version?: ModuleVersion;
/** Signer: viemWallet or ethers signer. Ingested when passed into smartAccount */
signer: SmartAccountSigner;
}

export type MultiChainUserOpDto = {
/** window end timestamp */
validUntil?: number;
/** window start timestamp */
validAfter?: number;
chainId: number;
userOp: Partial<UserOperationStruct>;
Expand All @@ -112,11 +146,15 @@ export interface BaseSessionKeyData {
}

export interface ERC20SessionKeyData extends BaseSessionKeyData {
/** ERC20 token address */
token: Hex;
/** Recipient address */
recipient: Hex;
/** ERC20 amount (Bigint) */
maxAmount: bigint;
}

export interface SessionValidationModuleConfig {
/** Address of the module */
moduleAddress: string;
}
63 changes: 63 additions & 0 deletions packages/modules/tests/ecdsaValidationModule.e2e.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { PaymasterMode } from "@biconomy/paymaster";
import { TestData } from "../../../tests";
import { createSmartAccountClient } from "../../account/src/index";
import { Hex, encodeFunctionData, parseAbi } from "viem";
import { DEFAULT_MULTICHAIN_MODULE, createECDSAOwnershipValidationModule } from "@biconomy/modules";

describe("Account with ECDSAOwnershipValidationModule Module Tests", () => {
let mumbai: TestData;
let baseSepolia: TestData;

beforeEach(() => {
// @ts-ignore: Comes from setup-e2e-tests
[mumbai, baseSepolia] = testDataPerChain;
});

it("should create a ECDSAOwnershipValidationModule with signer", async () => {
const {
bundlerUrl,
whale: { viemWallet: signer },
} = mumbai;

const defaultValidationModule = await createECDSAOwnershipValidationModule({ signer });
// Should not require a signer or chainId
const smartAccount = await createSmartAccountClient({
bundlerUrl,
defaultValidationModule,
signer,
});
const address = await smartAccount.getAccountAddress();
expect(address).toBeTruthy();
expect(smartAccount.activeValidationModule).toEqual(defaultValidationModule);
});

it("should create a ECDSAOwnershipValidationModule without signer", async () => {
const {
bundlerUrl,
whale: { viemWallet: signer },
} = mumbai;

const defaultValidationModule = await createECDSAOwnershipValidationModule({ signer });
// Should not require a signer or chainId
const smartAccount = await createSmartAccountClient({
bundlerUrl,
defaultValidationModule,
});
const address = await smartAccount.getAccountAddress();
expect(address).toBeTruthy();
expect(smartAccount.activeValidationModule).toEqual(defaultValidationModule);
});

it("should create a ECDSAOwnershipValidationModule by default, without explicitly setting it on the smart account", async () => {
const {
bundlerUrl,
whale: { viemWallet: signer },
} = mumbai;
const defaultValidationModule = await createECDSAOwnershipValidationModule({ signer });
const smartAccount = await createSmartAccountClient({ bundlerUrl, signer });
const address = await smartAccount.getAccountAddress();
expect(address).toBeTruthy();
const smartAccountValidationModuleAddress = await smartAccount.activeValidationModule.getAddress();
expect(smartAccountValidationModuleAddress).toEqual(defaultValidationModule.moduleAddress);
});
});

0 comments on commit 1a8f296

Please sign in to comment.