Skip to content

Commit

Permalink
chore: fix deployment state
Browse files Browse the repository at this point in the history
  • Loading branch information
joepegler committed Aug 29, 2024
1 parent a32871f commit 82e935e
Show file tree
Hide file tree
Showing 16 changed files with 257 additions and 139 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@
"clean": "rimraf ./dist/_esm ./dist/_cjs ./dist/_types ./dist/tsconfig",
"test": "vitest -c ./tests/vitest.config.ts",
"test:watch": "bun run test dev",
"playground": "RUN_PLAYGROUND=true bun run test -t=Playground",
"playground:watch": "RUN_PLAYGROUND=true bun run test -t=Playground --watch",
"playground": "RUN_PLAYGROUND=true vitest -c ./tests/vitest.config.ts -t=playground",
"playground:watch": "RUN_PLAYGROUND=true bun run test -t=playground --watch",
"size": "size-limit",
"docs": "typedoc --tsconfig ./tsconfig/tsconfig.esm.json",
"docs:deploy": "bun run docs && gh-pages -d docs",
Expand Down
21 changes: 15 additions & 6 deletions src/account/BaseSmartContractAccount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,16 +201,21 @@ export abstract class BaseSmartContractAccount<
validationMode?: typeof MODE_VALIDATION | typeof MODE_MODULE_ENABLE
): Promise<bigint>

private async _isDeployed(): Promise<boolean> {
const contractCode = await this.publicClient.getBytecode({
address: await this.getAddress()
})
return (contractCode?.length ?? 0) > 2
}

async getInitCode(): Promise<Hex> {
if (this.deploymentState === DeploymentState.DEPLOYED) {
return "0x"
}

const contractCode = await this.publicClient.getBytecode({
address: await this.getAddress()
})
const isDeployed = await this._isDeployed()

if ((contractCode?.length ?? 0) > 2) {
if (isDeployed) {
this.deploymentState = DeploymentState.DEPLOYED
return "0x"
}
Expand Down Expand Up @@ -273,7 +278,7 @@ export abstract class BaseSmartContractAccount<
return this.entryPointAddress
}

async isAccountDeployed(): Promise<boolean> {
async isAccountDeployed(forceFetch = false): Promise<boolean> {

Check failure on line 281 in src/account/BaseSmartContractAccount.ts

View workflow job for this annotation

GitHub Actions / size report

'forceFetch' is declared but its value is never read.
return (await this.getDeploymentState()) === DeploymentState.DEPLOYED
}

Expand All @@ -284,9 +289,13 @@ export abstract class BaseSmartContractAccount<
? DeploymentState.DEPLOYED
: DeploymentState.NOT_DEPLOYED
}
if (this.deploymentState === DeploymentState.NOT_DEPLOYED) {
if (await this._isDeployed()) {
this.deploymentState = DeploymentState.DEPLOYED
}
}
return this.deploymentState
}

/**
* https://eips.ethereum.org/EIPS/eip-4337#first-time-account-creation
* The initCode field (if non-zero length) is parsed as a 20-byte address,
Expand Down
33 changes: 15 additions & 18 deletions src/account/NexusSmartAccount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -723,6 +723,7 @@ export class NexusSmartAccount extends BaseSmartContractAccount {
if (await this.isAccountDeployed()) return "0x"

const factoryData = (await this.getFactoryData()) as Hex

return concatHex([this.factoryAddress, factoryData])
}

Expand Down Expand Up @@ -1035,16 +1036,12 @@ export class NexusSmartAccount extends BaseSmartContractAccount {
* const { success, receipt } = await wait();
*
*/
async sendUserOp(
userOp: Partial<UserOperationStruct>
): Promise<UserOpResponse> {
// biome-ignore lint/performance/noDelete: <explanation>
delete userOp.signature
const userOperation = await this.signUserOp(userOp)

const bundlerResponse = await this.sendSignedUserOp(userOperation)

return bundlerResponse
async sendUserOp({
signature,
...userOpWithoutSignature
}: Partial<UserOperationStruct>): Promise<UserOpResponse> {
const userOperation = await this.signUserOp(userOpWithoutSignature)
return await this.sendSignedUserOp(userOperation)
}

/**
Expand Down Expand Up @@ -1322,13 +1319,12 @@ export class NexusSmartAccount extends BaseSmartContractAccount {
: [manyOrOneTransactions],
buildUseropDto
)
const payload = await this.sendUserOp(userOp)
this.setDeploymentState(payload) // Don't wait
return payload
const response = await this.sendUserOp(userOp)
this.setDeploymentState(response) // don't wait for this to finish...
return response
}

private async setDeploymentState({ wait }: UserOpResponse) {
if (this.deploymentState === DeploymentState.DEPLOYED) return
public async setDeploymentState({ wait }: UserOpResponse) {
const { success } = await wait()
if (success) {
this.deploymentState = DeploymentState.DEPLOYED
Expand Down Expand Up @@ -1394,7 +1390,8 @@ export class NexusSmartAccount extends BaseSmartContractAccount {
const dummySignatureFetchPromise = this.getDummySignatures()
const [nonceFromFetch, dummySignature] = await Promise.all([
this.getBuildUserOpNonce(buildUseropDto?.nonceOptions),
dummySignatureFetchPromise
dummySignatureFetchPromise,
this.getInitCode() // Not used, but necessary to determine if the account is deployed. Will return immediately if the account is already deployed
])

if (transactions.length === 0) {
Expand Down Expand Up @@ -1724,13 +1721,13 @@ export class NexusSmartAccount extends BaseSmartContractAccount {
async isModuleInstalled(module: Module) {
if (await this.isAccountDeployed()) {
const accountContract = await this._getAccountContract()
return await accountContract.read.isModuleInstalled([
const result = await accountContract.read.isModuleInstalled([
BigInt(moduleTypeIds[module.type]),
module.moduleAddress,
module.data ?? "0x"
])
return result
}
Logger.warn("A module cannot be installed on an undeployed account")
return false
}

Expand Down
4 changes: 3 additions & 1 deletion src/bundler/utils/HelperFunction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ function decodeErrorCode(errorCode: string) {
"0x40d3d1a40000000000000000000000004d8249d21c9553b1bd23cabf611011376dd3416a":
"LinkedList_EntryAlreadyInList",
"0x40d3d1a40000000000000000000000004b8306128aed3d49a9d17b99bf8082d4e406fa1f":
"LinkedList_EntryAlreadyInList"
"LinkedList_EntryAlreadyInList",
"0x40d3d1a4000000000000000000000000d98238bbaea4f91683d250003799ead31d7f5c55":
"Error: Custom error message about the K1Validator contract"
// Add more error codes and their corresponding human-readable messages here
}
const decodedError = errorMap[errorCode] || errorCode
Expand Down
4 changes: 2 additions & 2 deletions tests/account.read.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ import {
} from "./src/testUtils"
import type { MasterClient, NetworkConfig } from "./src/testUtils"

const NETWORK_TYPE: TestFileNetworkType = "GLOBAL"
const NETWORK_TYPE: TestFileNetworkType = "COMMON_LOCALHOST"

describe("account.read", () => {
let network: NetworkConfig
Expand All @@ -66,7 +66,7 @@ describe("account.read", () => {
let smartAccountAddress: Hex

beforeAll(async () => {
network = await toNetwork(NETWORK_TYPE)
network = (await toNetwork(NETWORK_TYPE)) as NetworkConfig

chain = network.chain
bundlerUrl = network.bundlerUrl
Expand Down
2 changes: 1 addition & 1 deletion tests/account.write.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
} from "./src/testUtils"
import type { MasterClient, NetworkConfig } from "./src/testUtils"

const NETWORK_TYPE: TestFileNetworkType = "LOCAL"
const NETWORK_TYPE: TestFileNetworkType = "FILE_LOCALHOST"

describe("account.write", () => {
let network: NetworkConfig
Expand Down
25 changes: 3 additions & 22 deletions tests/modules.k1Validator.write.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
encodePacked
} from "viem"
import { afterAll, beforeAll, describe, expect, test } from "vitest"
import { createK1ValidatorModule, getRandomSigner } from "../src"
import addresses from "../src/__contracts/addresses"
import {
type NexusSmartAccount,
Expand All @@ -28,7 +27,7 @@ import {
} from "./src/testUtils"
import type { MasterClient, NetworkConfig } from "./src/testUtils"

const NETWORK_TYPE: TestFileNetworkType = "LOCAL"
const NETWORK_TYPE: TestFileNetworkType = "FILE_LOCALHOST"

describe("modules.k1Validator.write", () => {
let network: NetworkConfig
Expand Down Expand Up @@ -110,40 +109,22 @@ describe("modules.k1Validator.write", () => {
})

test("should install k1 Validator with 1 owner", async () => {
// console.log(smartAccount.activeValidationModule, addresses.K1Validator)
const isInstalledBefore = await smartAccount.isModuleInstalled({
type: "validator",
moduleAddress: addresses.K1Validator
})

const modules = await smartAccount.getInstalledModules()

if (!isInstalledBefore) {
const { wait } = await smartAccount.installModule({
moduleAddress: addresses.K1Validator,
type: "validator",
data: encodePacked(["address"], [await smartAccount.getAddress()])
})

console.log("waiting....")
const { success: installSuccess } = await wait()
console.log({ installSuccess })

expect(installSuccess).toBe(true)

const k1ValidationModule = await createK1ValidatorModule(
smartAccount.getSigner()
)

const { wait: waitUninstall } = await smartAccount.uninstallModule({
moduleAddress: addresses.K1Validator,
type: "validator",
data: encodePacked(["address"], [await smartAccount.getAddress()])
})
console.log("waiting....")
const { success: successUninstall } = await waitUninstall()
console.log({ successUninstall })

smartAccount.setActiveValidationModule(k1ValidationModule)
expect(successUninstall).toBe(true)
}
}, 60000)

Expand Down
2 changes: 1 addition & 1 deletion tests/modules.ownableExecutor.read.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import {
} from "./src/testUtils"
import type { MasterClient, NetworkConfig } from "./src/testUtils"

const NETWORK_TYPE: TestFileNetworkType = "LOCAL"
const NETWORK_TYPE: TestFileNetworkType = "FILE_LOCALHOST"

describe("modules.ownable.executor.read", () => {
let network: NetworkConfig
Expand Down
2 changes: 1 addition & 1 deletion tests/modules.ownableExecutor.write.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
} from "./src/testUtils"
import type { MasterClient, NetworkConfig } from "./src/testUtils"

const NETWORK_TYPE: TestFileNetworkType = "LOCAL"
const NETWORK_TYPE: TestFileNetworkType = "FILE_LOCALHOST"

describe("modules.ownable.executor.write", () => {
let network: NetworkConfig
Expand Down
2 changes: 1 addition & 1 deletion tests/modules.ownableValidator.install.write.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
} from "./src/testUtils"
import type { MasterClient, NetworkConfig } from "./src/testUtils"

const NETWORK_TYPE: TestFileNetworkType = "LOCAL"
const NETWORK_TYPE: TestFileNetworkType = "FILE_LOCALHOST"

describe("modules.ownable.validator.install.write", () => {
let network: NetworkConfig
Expand Down
2 changes: 1 addition & 1 deletion tests/modules.ownableValidator.uninstall.write.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
} from "./src/testUtils"
import type { MasterClient, NetworkConfig } from "./src/testUtils"

const NETWORK_TYPE: TestFileNetworkType = "LOCAL"
const NETWORK_TYPE: TestFileNetworkType = "FILE_LOCALHOST"

describe("modules.ownable.validator.uninstall.write", () => {
let network: NetworkConfig
Expand Down
Loading

0 comments on commit 82e935e

Please sign in to comment.