@@ -6,9 +6,11 @@ import {
66 type Hex ,
77 type JsonRpcAccount ,
88 type LocalAccount ,
9+ type PrivateKeyAccount ,
910 type Transport ,
1011} from "viem" ;
1112import { readContract } from "viem/actions" ;
13+ import type { ToSmartAccountParameters } from "viem/account-abstraction" ;
1214import { LightAccountAbi_v1 } from "../abis/LightAccountAbi_v1.js" ;
1315import { LightAccountAbi_v2 } from "../abis/LightAccountAbi_v2.js" ;
1416import { LightAccountFactoryAbi_v1 } from "../abis/LightAccountFactoryAbi_v1.js" ;
@@ -27,6 +29,10 @@ import { toLightAccountBase, type LightAccountBase } from "./base.js";
2729import { BaseError , lowerAddress } from "@alchemy/common" ;
2830import { getAction } from "viem/utils" ;
2931import { LOGGER } from "../../logger.js" ;
32+ import { InvalidOwnerError } from "../../errors/InvalidOwnerError.js" ;
33+ import { lightAccountStaticImpl7702V2_1_0 } from "../lightAccountStaticImpl.js" ;
34+
35+ type LightAccountMode = "default" | "7702" ;
3036
3137export type LightAccount <
3238 TLightAccountVersion extends
@@ -39,15 +45,24 @@ export type LightAccount<
3945export type ToLightAccountParams <
4046 TLightAccountVersion extends
4147 LightAccountVersion < "LightAccount" > = LightAccountVersion < "LightAccount" > ,
48+ TMode extends LightAccountMode | undefined = LightAccountMode | undefined ,
4249> = {
4350 client : Client < Transport , Chain , JsonRpcAccount | LocalAccount | undefined > ;
4451 owner : JsonRpcAccount | LocalAccount ;
45- salt ?: bigint ;
4652 accountAddress ?: Address ;
47- factory ?: Address ;
48- factoryData ?: Hex ;
4953 version ?: TLightAccountVersion ;
50- } ;
54+ mode ?: TMode ;
55+ } & ( TMode extends "7702"
56+ ? {
57+ salt ?: never ;
58+ factory ?: never ;
59+ factoryData ?: never ;
60+ }
61+ : {
62+ salt ?: bigint ;
63+ factory ?: Address ;
64+ factoryData ?: Hex ;
65+ } ) ;
5166
5267/**
5368 * Creates a light account.
@@ -58,6 +73,7 @@ export type ToLightAccountParams<
5873export async function toLightAccount <
5974 TLightAccountVersion extends
6075 LightAccountVersion < "LightAccount" > = LightAccountVersion < "LightAccount" > ,
76+ TMode extends LightAccountMode = LightAccountMode ,
6177> ( {
6278 client,
6379 owner,
@@ -66,11 +82,15 @@ export async function toLightAccount<
6682 version = defaultLightAccountVersion ( ) as TLightAccountVersion ,
6783 factory = AccountVersionRegistry . LightAccount [ version ] . factoryAddress ,
6884 factoryData : factoryData_ ,
69- } : ToLightAccountParams < TLightAccountVersion > ) : Promise <
85+ mode,
86+ } : ToLightAccountParams < TLightAccountVersion , TMode > ) : Promise <
7087 LightAccount < TLightAccountVersion >
7188> {
89+ const is7702 = mode === "7702" ;
90+
7291 LOGGER . debug ( "toLightAccount:start" , {
7392 version,
93+ mode,
7494 hasAccountAddress : ! ! accountAddress_ ,
7595 } ) ;
7696
@@ -87,16 +107,26 @@ export async function toLightAccount<
87107
88108 const accountAddress =
89109 accountAddress_ ??
90- predictLightAccountAddress ( {
91- factoryAddress : factory ,
92- salt,
93- ownerAddress : owner . address ,
94- version,
95- } ) ;
110+ ( is7702 && owner . type === "local"
111+ ? owner . address
112+ : predictLightAccountAddress ( {
113+ factoryAddress : factory ,
114+ salt,
115+ ownerAddress : owner . address ,
116+ version,
117+ } ) ) ;
96118
97- LOGGER . debug ( "toLightAccount:address-resolved" , { accountAddress } ) ;
119+ LOGGER . debug ( "toLightAccount:address-resolved" , { accountAddress, is7702 } ) ;
98120
99121 const getFactoryArgs = async ( ) => {
122+ if ( is7702 ) {
123+ // EIP-7702 uses special factory address for EP 0.8
124+ return {
125+ factory : "0x7702000000000000000000000000000000000000" as Address ,
126+ factoryData : "0x" as Hex ,
127+ } as const ;
128+ }
129+
100130 const factoryData =
101131 factoryData_ ??
102132 encodeFunctionData ( {
@@ -111,6 +141,29 @@ export async function toLightAccount<
111141 } ;
112142 } ;
113143
144+ let authorization : ToSmartAccountParameters [ "authorization" ] ;
145+ if ( is7702 ) {
146+ LOGGER . debug ( "toLightAccount:7702-mode" ) ;
147+ if ( owner . type !== "local" ) {
148+ LOGGER . error ( "toLightAccount:invalid-owner-type" , {
149+ ownerType : owner . type ,
150+ } ) ;
151+ throw new InvalidOwnerError (
152+ `Owner of type ${ owner . type } is unsupported for 7702 mode.` ,
153+ ) ;
154+ }
155+ if ( owner . signAuthorization == null ) {
156+ LOGGER . error ( "toLightAccount:missing-signAuthorization" ) ;
157+ throw new InvalidOwnerError (
158+ "Owner must implement `signAuthorization` to be used with 7702 mode." ,
159+ ) ;
160+ }
161+ authorization = {
162+ account : owner as PrivateKeyAccount ,
163+ address : lightAccountStaticImpl7702V2_1_0 . delegationAddress ,
164+ } ;
165+ }
166+
114167 const baseAccount = await toLightAccountBase ( {
115168 client,
116169 owner,
@@ -119,6 +172,7 @@ export async function toLightAccount<
119172 type : "LightAccount" ,
120173 version,
121174 getFactoryArgs,
175+ authorization,
122176 } ) ;
123177
124178 return {
0 commit comments