Skip to content

Commit

Permalink
Merge pull request #114 from pimlicolabs/feat/EP-v0.7
Browse files Browse the repository at this point in the history
EntryPoint 0.7 support
  • Loading branch information
kristofgazso authored Feb 24, 2024
2 parents bb8fda4 + f58e283 commit 9755c3d
Show file tree
Hide file tree
Showing 87 changed files with 4,306 additions and 870 deletions.
5 changes: 5 additions & 0 deletions .changeset/big-adults-act.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"permissionless": minor
---

Add EntryPoint v0.7 support
3 changes: 1 addition & 2 deletions .changeset/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,5 @@
"updateInternalDependencies": "patch",
"___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": {
"onlyUpdatePeerDependentsWhenOutOfRange": true
},
"ignore": ["test"]
}
}
Binary file modified bun.lockb
Binary file not shown.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
"type": "module",
"sideEffects": false,
"devDependencies": {
"vitest": "^1.2.0",
"@vitest/coverage-v8": "^1.2.0",
"@biomejs/biome": "^1.0.0",
"@changesets/changelog-git": "^0.1.14",
"@changesets/changelog-github": "^0.4.8",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,42 @@
import dotenv from "dotenv"
import { UserOperation } from "permissionless"
import {
SignTransactionNotSupportedBySmartAccount,
signerToBiconomySmartAccount
} from "permissionless/accounts"
import { Address, Hex, decodeEventLog, getContract, zeroAddress } from "viem"
import {
http,
Account,
Address,
Chain,
Hex,
Transport,
WalletClient,
createWalletClient,
decodeEventLog,
getContract,
zeroAddress
} from "viem"
import { privateKeyToAccount } from "viem/accounts"
import { beforeAll, describe, expect, expectTypeOf, test } from "vitest"
import {
beforeAll,
beforeEach,
describe,
expect,
expectTypeOf,
test
} from "vitest"
import { EntryPointAbi } from "./abis/EntryPoint"
import { GreeterAbi, GreeterBytecode } from "./abis/Greeter"
import {
getBundlerClient,
getEntryPoint,
getPimlicoPaymasterClient,
getPrivateKeyAccount,
getPublicClient,
getSignerToBiconomyAccount,
getSmartAccountClient,
getTestingChain,
refillSmartAccount,
waitForNonceUpdate
} from "./utils"

Expand All @@ -40,6 +61,17 @@ beforeAll(() => {
* TODO: Should generify the basics test for every smart account & smart account client (address, signature, etc)
*/
describe("Biconomy Modular Smart Account (ECDSA module)", () => {
let walletClient: WalletClient<Transport, Chain, Account>

beforeEach(async () => {
const owner = getPrivateKeyAccount()
walletClient = createWalletClient({
account: owner,
chain: getTestingChain(),
transport: http(process.env.RPC_URL as string)
})
})

test("Account address", async () => {
const ecdsaSmartAccount = await getSignerToBiconomyAccount()

Expand Down Expand Up @@ -118,6 +150,11 @@ describe("Biconomy Modular Smart Account (ECDSA module)", () => {
account: await getSignerToBiconomyAccount()
})

await refillSmartAccount(
walletClient,
smartAccountClient.account.address
)

const response = await smartAccountClient.sendTransactions({
transactions: [
{
Expand All @@ -142,6 +179,10 @@ describe("Biconomy Modular Smart Account (ECDSA module)", () => {
const smartAccountClient = await getSmartAccountClient({
account: await getSignerToBiconomyAccount()
})
await refillSmartAccount(
walletClient,
smartAccountClient.account.address
)

const entryPointContract = getContract({
abi: EntryPointAbi,
Expand Down Expand Up @@ -185,7 +226,7 @@ describe("Biconomy Modular Smart Account (ECDSA module)", () => {
sponsorUserOperation: async ({
entryPoint: _entryPoint,
userOperation
}): Promise<UserOperation> => {
}) => {
const pimlicoPaymaster = getPimlicoPaymasterClient()
return pimlicoPaymaster.sponsorUserOperation({
userOperation,
Expand Down Expand Up @@ -248,7 +289,7 @@ describe("Biconomy Modular Smart Account (ECDSA module)", () => {
sponsorUserOperation: async ({
entryPoint: _entryPoint,
userOperation
}): Promise<UserOperation> => {
}) => {
const pimlicoPaymaster = getPimlicoPaymasterClient()
return pimlicoPaymaster.sponsorUserOperation({
userOperation,
Expand Down Expand Up @@ -316,7 +357,7 @@ describe("Biconomy Modular Smart Account (ECDSA module)", () => {
sponsorUserOperation: async ({
entryPoint: _entryPoint,
userOperation
}): Promise<UserOperation> => {
}) => {
const pimlicoPaymaster = getPimlicoPaymasterClient()
return pimlicoPaymaster.sponsorUserOperation({
userOperation,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,30 @@
import dotenv from "dotenv"
import {
BundlerClient,
ENTRYPOINT_ADDRESS_V07,
UserOperation,
WaitForUserOperationReceiptTimeoutError,
getAccountNonce
createBundlerClient,
createSmartAccountClient,
getAccountNonce,
walletClientToSmartAccountSigner
} from "permissionless"
import { signerToSimpleSmartAccount } from "permissionless/accounts"
import { ENTRYPOINT_ADDRESS_V06_TYPE } from "permissionless/types"
import { getUserOperationHash } from "permissionless/utils"
import { Address, type Hash, parseEther } from "viem"
import {
http,
Account,
Address,
Chain,
type Hash,
Transport,
WalletClient,
createWalletClient,
parseEther,
zeroAddress
} from "viem"
import { privateKeyToAccount } from "viem/accounts"
import {
beforeAll,
beforeEach,
Expand All @@ -20,8 +38,11 @@ import {
getBundlerClient,
getEntryPoint,
getEoaWalletClient,
getPrivateKeyAccount,
getPublicClient,
getSignerToSimpleSmartAccount,
getTestingChain,
refillSmartAccount,
waitForNonceUpdate
} from "./utils"

Expand All @@ -39,21 +60,28 @@ beforeAll(() => {
})

describe("BUNDLER ACTIONS", () => {
let bundlerClient: BundlerClient
let bundlerClient: BundlerClient<ENTRYPOINT_ADDRESS_V06_TYPE>
let walletClient: WalletClient<Transport, Chain, Account>

beforeEach(async () => {
const owner = getPrivateKeyAccount()
walletClient = createWalletClient({
account: owner,
chain: getTestingChain(),
transport: http(process.env.RPC_URL as string)
})
bundlerClient = getBundlerClient()
})

test("Supported entry points request", async () => {
test.skip("Supported entry points request", async () => {
const supportedEntryPoints = await bundlerClient.supportedEntryPoints()

expectTypeOf(supportedEntryPoints).toBeArray()
expect(supportedEntryPoints.length).toBeGreaterThan(0)
expect(supportedEntryPoints.includes(getEntryPoint())).toBe(true)
})

test("Chain id call", async () => {
test.skip("Chain id call", async () => {
const chainId = await bundlerClient.chainId()
const chain = getTestingChain()

Expand All @@ -63,58 +91,77 @@ describe("BUNDLER ACTIONS", () => {
})

test("Estimate user operation gas", async () => {
const publicClient = await getPublicClient()

const eoaWalletClient = getEoaWalletClient()

const userOperation = await buildUserOp(eoaWalletClient)
const simpleAccount = await signerToSimpleSmartAccount(publicClient, {
signer: privateKeyToAccount(
process.env.TEST_PRIVATE_KEY as Address
),
entryPoint: getEntryPoint(),
factoryAddress: process.env.FACTORY_ADDRESS as Address,
index: 3n
})

const gasParameters = await bundlerClient.estimateUserOperationGas({
userOperation,
const smartAccountClient = createSmartAccountClient({
account: simpleAccount,
chain: getTestingChain(),
transport: http(`${process.env.BUNDLER_RPC_HOST}`),
entryPoint: getEntryPoint()
})

expect(gasParameters.callGasLimit).toBeGreaterThan(BigInt(0))
expect(gasParameters.verificationGasLimit).toBeGreaterThan(BigInt(0))
expect(gasParameters.preVerificationGas).toBeGreaterThan(BigInt(0))
await eoaWalletClient.sendTransaction({
to: simpleAccount.address,
value: parseEther("1")
})

const response = await smartAccountClient.sendTransaction({
to: zeroAddress,
value: 0n
})
})

test("Sending user operation", async () => {
const eoaWalletClient = getEoaWalletClient()
test.skip("Sending user operation", async () => {
const publicClient = await getPublicClient()
const userOperation = await buildUserOp(eoaWalletClient)
const eoaWalletClient = getEoaWalletClient()

const entryPoint = getEntryPoint()
const chain = getTestingChain()
const bundlerClient = createBundlerClient({
chain: getTestingChain(),
transport: http(`${process.env.BUNDLER_RPC_HOST}`),
entryPoint: ENTRYPOINT_ADDRESS_V07
})

const simpleAccount = await signerToSimpleSmartAccount(publicClient, {
signer: walletClientToSmartAccountSigner(eoaWalletClient),
entryPoint: ENTRYPOINT_ADDRESS_V07,
factoryAddress: process.env.FACTORY_ADDRESS as Address
})

const gasParameters = await bundlerClient.estimateUserOperationGas(
{
userOperation,
entryPoint: getEntryPoint()
const smartAccountClient = createSmartAccountClient({
account: simpleAccount,
chain: getTestingChain(),
transport: http(`${process.env.BUNDLER_RPC_HOST}`),
sponsorUserOperation: async (args) => {
return args.userOperation
},
{
[userOperation.sender]: {
balance: 1000n
}
}
)
entryPoint: ENTRYPOINT_ADDRESS_V07
})

userOperation.callGasLimit = gasParameters.callGasLimit
userOperation.verificationGasLimit = gasParameters.verificationGasLimit
userOperation.preVerificationGas = gasParameters.preVerificationGas
await refillSmartAccount(
walletClient,
smartAccountClient.account.address
)

userOperation.signature = await eoaWalletClient.signMessage({
account: eoaWalletClient.account,
message: {
raw: getUserOperationHash({
userOperation,
entryPoint,
chainId: chain.id
})
}
})
const userOperation =
await smartAccountClient.prepareUserOperationRequest({
userOperation: {
callData: "0x"
}
})

const userOpHash = await bundlerClient.sendUserOperation({
userOperation: userOperation,
entryPoint: entryPoint as Address
userOperation: userOperation
})

expectTypeOf(userOpHash).toBeString()
Expand Down Expand Up @@ -143,7 +190,9 @@ describe("BUNDLER ACTIONS", () => {
await bundlerClient.getUserOperationByHash({ hash: userOpHash })

expect(userOperationFromUserOpHash).not.toBeNull()
expect(userOperationFromUserOpHash?.entryPoint).toBe(entryPoint)
expect(userOperationFromUserOpHash?.entryPoint).toBe(
ENTRYPOINT_ADDRESS_V07
)
expect(userOperationFromUserOpHash?.transactionHash).toBe(
userOperationReceipt?.receipt.transactionHash
)
Expand All @@ -163,16 +212,15 @@ describe("BUNDLER ACTIONS", () => {
// expect(newNonce).toBe(userOperation.nonce + BigInt(1))
}, 100000)

test("wait for user operation receipt fail", async () => {
test.skip("wait for user operation receipt fail", async () => {
const eoaWalletClient = getEoaWalletClient()
const userOperation = await buildUserOp(eoaWalletClient)

const entryPoint = getEntryPoint()
const chain = getTestingChain()

const gasParameters = await bundlerClient.estimateUserOperationGas({
userOperation,
entryPoint: getEntryPoint()
userOperation
})

userOperation.callGasLimit = gasParameters.callGasLimit
Expand Down
Loading

0 comments on commit 9755c3d

Please sign in to comment.