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

refactor OwnableExecutor module & fixed tests #580

Closed
wants to merge 2 commits into from
Closed
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
Binary file modified bun.lockb
Binary file not shown.
4 changes: 1 addition & 3 deletions src/__contracts/addresses.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
// The contents of this folder is auto-generated. Please do not edit as your changes are likely to be overwritten

import type { Hex } from "viem"
export const addresses: Record<string, Hex> = {
Nexus: "0x21f4C007C9f091B93B7C1C6911E13ACcd3DAd403",
K1Validator: "0x6854688d3D9A87a33Addd5f4deB5cea1B97fa5b7",
K1ValidatorFactory: "0x976869CF9c5Dd5046b41963EF1bBcE62b5366869",
UniActionPolicy: "0x28120dC008C36d95DE5fa0603526f219c1Ba80f6"
} as const
export default addresses
export default addresses
5 changes: 2 additions & 3 deletions src/account/BaseSmartContractAccount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ export enum DeploymentState {

export abstract class BaseSmartContractAccount<
TSigner extends SmartAccountSigner = SmartAccountSigner
> implements ISmartContractAccount<TSigner>
{
> implements ISmartContractAccount<TSigner> {
protected factoryAddress: Address

protected deploymentState: DeploymentState = DeploymentState.UNDEFINED
Expand Down Expand Up @@ -197,7 +196,7 @@ export abstract class BaseSmartContractAccount<
): Promise<bigint>

private async _isDeployed(): Promise<boolean> {
const contractCode = await this.publicClient.getBytecode({
const contractCode = await this.publicClient.getCode({
address: await this.getAddress()
})
return (contractCode?.length ?? 0) > 2
Expand Down
113 changes: 29 additions & 84 deletions src/account/NexusSmartAccount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
type Hex,
type PublicClient,
type TypedDataDefinition,
type WalletClient,
concat,
concatHex,
decodeFunctionData,
Expand All @@ -31,7 +30,6 @@ import { NexusAbi } from "../__contracts/abi"
import {
Bundler,
type GetUserOperationGasPriceReturnType,
type UserOpReceipt,
type UserOpResponse
} from "../bundler/index.js"
import type { IBundler } from "../bundler/interfaces/IBundler.js"
Expand Down Expand Up @@ -109,10 +107,7 @@ export class NexusSmartAccount extends BaseSmartContractAccount {

bundler?: IBundler

private accountContract?: GetContractReturnType<
typeof NexusAbi,
PublicClient | WalletClient
>
private accountContract?: GetContractReturnType<typeof NexusAbi, PublicClient>;

// private scanForUpgradedAccountsFromV1!: boolean

Expand All @@ -125,7 +120,6 @@ export class NexusSmartAccount extends BaseSmartContractAccount {
activeValidationModule!: BaseValidationModule

installedExecutors: BaseExecutionModule[] = []
activeExecutionModule?: BaseExecutionModule
k1ValidatorAddress: Address

private constructor(
Expand Down Expand Up @@ -583,20 +577,18 @@ export class NexusSmartAccount extends BaseSmartContractAccount {
return this.sendTransaction(txs, buildUseropDto)
}

async _getAccountContract(): Promise<
GetContractReturnType<typeof NexusAbi, PublicClient>
> {
async _getAccountContract(): Promise<GetContractReturnType<typeof NexusAbi, PublicClient>> {
if (await this.isAccountDeployed()) {
if (!this.accountContract) {
this.accountContract = getContract({
address: await this.getAddress(),
abi: NexusAbi,
client: this.publicClient as PublicClient
})
client: this.publicClient
}) as GetContractReturnType<typeof NexusAbi, PublicClient>;
}
return this.accountContract
return this.accountContract;
}
throw new Error(ERROR_MESSAGES.ACCOUNT_NOT_DEPLOYED)
throw new Error(ERROR_MESSAGES.ACCOUNT_NOT_DEPLOYED);
}

isActiveValidationModuleDefined(): boolean {
Expand Down Expand Up @@ -651,20 +643,6 @@ export class NexusSmartAccount extends BaseSmartContractAccount {
throw new Error("Validation module address is required")
}

/**
* Sets the active executor module on the NexusSmartAccount instance
* @param executorModule - Address of the executor module
* @param data - Initialization data for the executor module
*
* @returns Promise<BaseExecutionModule> - The BaseExecutionModule instance.
*/
setActiveExecutionModule(
executorModule: BaseExecutionModule
): BaseExecutionModule {
this.activeExecutionModule = executorModule
return this.activeExecutionModule
}

setDefaultValidationModule(
validationModule: BaseValidationModule
): NexusSmartAccount {
Expand Down Expand Up @@ -1123,18 +1101,18 @@ export class NexusSmartAccount extends BaseSmartContractAccount {

if (!userOp.maxFeePerGas && !userOp.maxPriorityFeePerGas) {
const feeData = await this.publicClient.estimateFeesPerGas()
if (feeData.maxFeePerGas?.toString()) {
if (feeData.maxFeePerGas) {
finalUserOp.maxFeePerGas = feeData.maxFeePerGas
} else if (feeData.gasPrice?.toString()) {
} else if (feeData.gasPrice) {
finalUserOp.maxFeePerGas = feeData.gasPrice
} else {
finalUserOp.maxFeePerGas = await this.publicClient.getGasPrice()
}

if (feeData.maxPriorityFeePerGas?.toString()) {
if (feeData.maxPriorityFeePerGas) {
finalUserOp.maxPriorityFeePerGas = feeData.maxPriorityFeePerGas
} else if (feeData.gasPrice?.toString()) {
finalUserOp.maxPriorityFeePerGas = feeData.gasPrice ?? 0n
} else if (feeData.gasPrice) {
finalUserOp.maxPriorityFeePerGas = feeData.gasPrice
} else {
finalUserOp.maxPriorityFeePerGas = await this.publicClient.getGasPrice()
}
Expand Down Expand Up @@ -1343,19 +1321,19 @@ export class NexusSmartAccount extends BaseSmartContractAccount {
}
}

async sendTransactionWithExecutor(
manyOrOneTransactions: Transaction | Transaction[],
ownedAccountAddress?: Address
// buildUseropDto?: BuildUserOpOptions
): Promise<UserOpReceipt> {
return await this.executeFromExecutor(
Array.isArray(manyOrOneTransactions)
? manyOrOneTransactions
: [manyOrOneTransactions],
ownedAccountAddress
// buildUseropDto
)
}
// async sendTransactionWithExecutor(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comments

// manyOrOneTransactions: Transaction | Transaction[],
// ownedAccountAddress?: Address
// // buildUseropDto?: BuildUserOpOptions
// ): Promise<UserOpReceipt> {
// return await this.executeFromExecutor(
// Array.isArray(manyOrOneTransactions)
// ? manyOrOneTransactions
// : [manyOrOneTransactions],
// ownedAccountAddress
// // buildUseropDto
// )
// }

/**
* Builds a user operation
Expand Down Expand Up @@ -1663,7 +1641,7 @@ export class NexusSmartAccount extends BaseSmartContractAccount {
const accountAddress = this.accountAddress ?? (await this.getAddress())

// Check that the account has not already been deployed
const byteCode = await this.publicClient?.getBytecode({
const byteCode = await this.publicClient?.getCode({
address: accountAddress as Hex
})

Expand Down Expand Up @@ -1718,7 +1696,7 @@ export class NexusSmartAccount extends BaseSmartContractAccount {
["address", "bytes"],
[
this.activeValidationModule.getAddress() ??
this.defaultValidationModule.getAddress(),
this.defaultValidationModule.getAddress(),
signature
]
)
Expand Down Expand Up @@ -1821,7 +1799,7 @@ export class NexusSmartAccount extends BaseSmartContractAccount {
["address", "bytes"],
[
this.activeValidationModule.getAddress() ??
this.defaultValidationModule.getAddress(),
this.defaultValidationModule.getAddress(),
signatureData
]
)
Expand Down Expand Up @@ -1866,6 +1844,8 @@ export class NexusSmartAccount extends BaseSmartContractAccount {
case "validator":
case "executor":
case "hook":
console.log(module.data, "module.data");

execution = await this._installModule({
moduleAddress: module.moduleAddress,
type: module.type,
Expand Down Expand Up @@ -2057,41 +2037,6 @@ export class NexusSmartAccount extends BaseSmartContractAccount {
throw new Error("Module is not installed")
}

private async executeFromExecutor(
transactions: Transaction[],
ownedAccountAddress?: Address
// buildUseropDto?: BuildUserOpOptions
): Promise<UserOpReceipt> {
if (this.activeExecutionModule) {
if (transactions.length > 1) {
const executions: { target: Hex; value: bigint; callData: Hex }[] =
transactions.map((tx) => {
return {
target: tx.to as Hex,
callData: (tx.data ?? "0x") as Hex,
value: BigInt(tx.value ?? 0n)
}
})
return await this.activeExecutionModule?.execute(
executions,
ownedAccountAddress
)
}
const execution = {
target: transactions[0].to as Hex,
callData: (transactions[0].data ?? "0x") as Hex,
value: BigInt(transactions[0].value ?? 0n)
}
return await this.activeExecutionModule.execute(
execution,
ownedAccountAddress
)
}
throw new Error(
"Please set an active executor module before running this method."
)
}

/**
* Checks if the account contract supports a specific execution mode.
* @param mode - The execution mode to check, represented as a viem Address.
Expand Down
9 changes: 4 additions & 5 deletions src/modules/base/BaseExecutionModule.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import type { Address } from "viem"
import type { UserOpReceipt } from "../../bundler/index.js"
import { BaseModule } from "../base/BaseModule.js"
import type { Execution } from "../utils/Types.js"
import { type NexusSmartAccount, type UserOperationStruct } from "../../account/index.js"

export abstract class BaseExecutionModule extends BaseModule {
abstract execute(
abstract getExecuteUserOp(
execution: Execution | Execution[],
ownedAccountAddress?: Address
): Promise<UserOpReceipt>
smartAccount?: NexusSmartAccount
): Promise<Partial<UserOperationStruct>>
}
Loading