Skip to content

Commit

Permalink
Pim 1017 (#188)
Browse files Browse the repository at this point in the history
* Light account factory v2.0.0 setup

* 1.1.0 support

* Implemented light client signMessage

* Light account v1.1.0 support

* Preffify light account

* Cleanup

* Cleanup tests

* Fix typo & call data encoding

* Remove any mention of the v2.0.0 light account

* Add changeset

* Fix changeset typo
  • Loading branch information
pavlovdog authored May 2, 2024
1 parent 8465706 commit 976884b
Show file tree
Hide file tree
Showing 9 changed files with 555 additions and 4 deletions.
5 changes: 5 additions & 0 deletions .changeset/tidy-rats-bow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"permissionless": minor
---

Added Alchemy's LightAccount support v1.1.0

Large diffs are not rendered by default.

40 changes: 38 additions & 2 deletions packages/permissionless-test/mock-aa-infra/alto/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
parseEther
} from "viem"
import { mnemonicToAccount } from "viem/accounts"
import { sendTransaction } from "viem/actions"
import { getTransactionReceipt, sendTransaction } from "viem/actions"
import { foundry } from "viem/chains"
import {
BICONOMY_ACCOUNT_V2_LOGIC_CREATECALL,
Expand All @@ -25,6 +25,7 @@ import {
KERNEL_V07_ECDSA_VALIDATOR_V3_CREATECALL,
KERNEL_V07_FACTORY_CREATECALL,
KERNEL_V07_META_FACTORY_CREATECALL,
LIGHT_ACCOUNT_FACTORY_V110_CREATECALL,
SAFE_MULTI_SEND_CALL_ONLY_CREATECALL,
SAFE_MULTI_SEND_CREATECALL,
SAFE_PROXY_FACTORY_CREATECALL,
Expand Down Expand Up @@ -311,6 +312,17 @@ const main = async () => {
})
.then(() => console.log("[KERNEL] Deploying V0.7 META FACTORY"))

walletClient
.sendTransaction({
to: DETERMINISTIC_DEPLOYER,
data: LIGHT_ACCOUNT_FACTORY_V110_CREATECALL,
gas: 15_000_000n,
nonce: nonce++
})
.then(() =>
console.log("[LIGHT ACCOUNT] Deploying V1.1.0 LightAccount Factory")
)

let onchainNonce = 0
do {
onchainNonce = await client.getTransactionCount({
Expand Down Expand Up @@ -354,6 +366,28 @@ const main = async () => {
address: kernelFactoryOwner
})

// ==== SETUP ALCHEMY LIGHT ACCOUNT CONTRACTS ==== //
const alchemyLightClientOwner = "0xDdF32240B4ca3184De7EC8f0D5Aba27dEc8B7A5C"
await anvilClient.setBalance({
address: alchemyLightClientOwner,
value: parseEther("100")
})

await anvilClient.impersonateAccount({
address: alchemyLightClientOwner
})

await sendTransaction(walletClient, {
account: alchemyLightClientOwner,
to: "0x0000000000400CdFef5E2714E63d8040b700BC24" /* light account v2.0.0 factory */,
data: "0xfbb1c3d40000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000016345785d8a0000",
value: parseEther("0.1")
})

await anvilClient.stopImpersonatingAccount({
address: alchemyLightClientOwner
})

await verifyDeployed([
"0x4e59b44847b379578588920ca78fbf26c0b4956c",
"0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7",
Expand Down Expand Up @@ -381,7 +415,9 @@ const main = async () => {
"0x8104e3Ad430EA6d354d013A6789fDFc71E671c43",
"0x94F097E1ebEB4ecA3AAE54cabb08905B239A7D27",
"0x6723b44Abeec4E71eBE3232BD5B455805baDD22f",
"0xd703aaE79538628d27099B8c4f621bE4CCd142d5"
"0xd703aaE79538628d27099B8c4f621bE4CCd142d5",
"0x00004EC70002a32400f8ae005A26081065620D20", // LightAccountFactory V1.1.0
"0xae8c656ad28F2B59a196AB61815C16A0AE1c3cba" // LightAccount V1.1.0 implementation
])
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
SignTransactionNotSupportedBySmartAccount,
signerToBiconomySmartAccount,
signerToEcdsaKernelSmartAccount,
signerToLightSmartAccount,
signerToSafeSmartAccount,
signerToSimpleSmartAccount
} from "permissionless/accounts"
Expand Down Expand Up @@ -40,14 +41,30 @@ import {
fund,
getBiconomyClient,
getBundlerClient,
getFactoryAddress,
getKernelEcdsaClient,
getLightAccountClient,
getPimlicoPaymasterClient,
getPublicClient,
getSafeClient,
getSimpleAccountClient
} from "../utils"

describe.each([
{
name: "Light V1.1.0",
getSmartAccountClient: async (
conf: AAParamType<ENTRYPOINT_ADDRESS_V06_TYPE>
) => getLightAccountClient(conf),
getSmartAccountSigner: async (conf: ExistingSignerParamType) =>
signerToLightSmartAccount(conf.publicClient, {
address: conf.existingAddress, // this is the field we are testing
signer: privateKeyToAccount(conf.privateKey),
entryPoint: ENTRYPOINT_ADDRESS_V06,
lightVersion: "v1.1.0"
}),
isEip1271Compliant: true
},
{
name: "Simple",
getSmartAccountClient: async (
Expand Down Expand Up @@ -311,7 +328,7 @@ describe.each([
}

expect(eventFound).toBeTruthy()
}, 5000)
}, 10000)

test("Can send multiple transactions with paymaster", async () => {
const smartClient = await getSmartAccountClient({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ describe.each([
}

expect(eventFound).toBeTruthy()
}, 5000)
}, 10000)

test("Can send multiple transactions with paymaster", async () => {
const smartClient = await getSmartAccountClient({
Expand Down
28 changes: 28 additions & 0 deletions packages/permissionless-test/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
type SmartAccount,
signerToBiconomySmartAccount,
signerToEcdsaKernelSmartAccount,
signerToLightSmartAccount,
signerToSafeSmartAccount,
signerToSimpleSmartAccount
} from "permissionless/accounts"
Expand Down Expand Up @@ -204,6 +205,33 @@ export const getSimpleAccountClient = async <T extends EntryPoint>({
})
}

export const getLightAccountClient = async <T extends EntryPoint>({
entryPoint,
paymasterClient,
privateKey = generatePrivateKey()
}: AAParamType<T>): Promise<
SmartAccountClient<T, Transport, Chain, SmartAccount<T>>
> => {
const smartAccount = await signerToLightSmartAccount<T, Transport, Chain>(
publicClient,
{
entryPoint,
signer: privateKeyToAccount(privateKey),
lightVersion: "v1.1.0"
}
)

// @ts-ignore
return createSmartAccountClient({
chain: foundry,
account: smartAccount,
bundlerTransport: http(ALTO_RPC),
middleware: {
// @ts-ignore
sponsorUserOperation: paymasterClient?.sponsorUserOperation
}
})
}
// Only supports v0.6 for now
export const getBiconomyClient = async ({
paymasterClient,
Expand Down
16 changes: 16 additions & 0 deletions packages/permissionless/accounts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,17 @@ import {
signerToSimpleSmartAccount
} from "./simple/signerToSimpleSmartAccount"

import {
type PrivateKeyToLightSmartAccountParameters,
privateKeyToLightSmartAccount
} from "./light/privateKeyToLightSmartAccount"

import {
type LightSmartAccount,
type SignerToLightSmartAccountParameters,
signerToLightSmartAccount
} from "./light/signerToLightSmartAccount"

import {
type PrivateKeyToSafeSmartAccountParameters,
privateKeyToSafeSmartAccount
Expand Down Expand Up @@ -53,9 +64,12 @@ export {
signerToSafeSmartAccount,
type SimpleSmartAccount,
signerToSimpleSmartAccount,
type LightSmartAccount,
signerToLightSmartAccount,
SignTransactionNotSupportedBySmartAccount,
privateKeyToBiconomySmartAccount,
privateKeyToSimpleSmartAccount,
privateKeyToLightSmartAccount,
type SmartAccount,
privateKeyToSafeSmartAccount,
type KernelEcdsaSmartAccount,
Expand All @@ -64,8 +78,10 @@ export {
signerToBiconomySmartAccount,
toSmartAccount,
type SignerToSimpleSmartAccountParameters,
type SignerToLightSmartAccountParameters,
type SignerToSafeSmartAccountParameters,
type PrivateKeyToSimpleSmartAccountParameters,
type PrivateKeyToLightSmartAccountParameters,
type PrivateKeyToSafeSmartAccountParameters,
type SignerToEcdsaKernelSmartAccountParameters,
type SignerToBiconomySmartAccountParameters,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { type Chain, type Client, type Hex, type Transport } from "viem"
import { privateKeyToAccount } from "viem/accounts"
import type { ENTRYPOINT_ADDRESS_V06_TYPE, Prettify } from "../../types"
import {
type LightSmartAccount,
type SignerToLightSmartAccountParameters,
signerToLightSmartAccount
} from "./signerToLightSmartAccount"

export type PrivateKeyToLightSmartAccountParameters<
entryPoint extends ENTRYPOINT_ADDRESS_V06_TYPE
> = Prettify<
{
privateKey: Hex
} & Omit<SignerToLightSmartAccountParameters<entryPoint>, "signer">
>

/**
* @description Creates an Simple Account from a private key.
*
* @returns A Private Key Simple Account.
*/
export async function privateKeyToLightSmartAccount<
entryPoint extends ENTRYPOINT_ADDRESS_V06_TYPE,
TTransport extends Transport = Transport,
TChain extends Chain | undefined = Chain | undefined
>(
client: Client<TTransport, TChain, undefined>,
{ privateKey, ...rest }: PrivateKeyToLightSmartAccountParameters<entryPoint>
): Promise<LightSmartAccount<entryPoint, TTransport, TChain>> {
const privateKeyAccount = privateKeyToAccount(privateKey)

return signerToLightSmartAccount(client, {
signer: privateKeyAccount,
...rest
})
}
Loading

0 comments on commit 976884b

Please sign in to comment.