@@ -20,7 +20,7 @@ import {
2020 noopMiddleware ,
2121 resolveProperties ,
2222} from "@aa-sdk/core" ;
23- import { fromHex , isHex , type Hex } from "viem" ;
23+ import { fromHex , isHex , toHex , type Hex } from "viem" ;
2424import type { AlchemySmartAccountClient } from "../client/smartAccountClient.js" ;
2525import type { AlchemyTransport } from "../alchemyTransport.js" ;
2626import { alchemyFeeEstimator } from "./feeEstimator.js" ;
@@ -62,7 +62,10 @@ interface AlchemyGasAndPaymasterAndDataMiddlewareParams {
6262
6363export type PolicyToken = {
6464 address : string ;
65+ maxTokenAmount : bigint ;
6566 approvalMode : ApprovalMode ;
67+ erc20Name : string ;
68+ version : string ;
6669} ;
6770
6871export enum ApprovalMode {
@@ -205,6 +208,79 @@ export function alchemyGasAndPaymasterAndDataMiddleware(
205208 : { } ) ,
206209 } ) ;
207210
211+ let erc20Context = undefined ;
212+ if (
213+ policyToken !== undefined &&
214+ policyToken . approvalMode == ApprovalMode . PERMIT
215+ ) {
216+ // get a paymaster address
217+ let paymasterAddress = "0x" ;
218+ const paymasterData = await (
219+ client as AlchemySmartAccountClient
220+ ) . request ( {
221+ method : "pm_getPaymasterStubData" ,
222+ params : [
223+ userOp ,
224+ account . getEntryPoint ( ) . address ,
225+ toHex ( client . chain . id ) ,
226+ {
227+ policyId : Array . isArray ( policyId ) ? policyId [ 0 ] : policyId ,
228+ } ,
229+ ] ,
230+ } ) ;
231+ paymasterAddress = paymasterData . paymaster
232+ ? paymasterData . paymaster
233+ : paymasterData . paymasterAndData
234+ ? paymasterData . paymasterAndData . slice ( 0 , 42 )
235+ : "0x" ;
236+ const typed_permit_data = {
237+ types : {
238+ Permit : [
239+ {
240+ name : "owner" ,
241+ type : "address" ,
242+ } ,
243+ {
244+ name : "spender" ,
245+ type : "address" ,
246+ } ,
247+ {
248+ name : "value" ,
249+ type : "uint256" ,
250+ } ,
251+ {
252+ name : "nonce" ,
253+ type : "uint256" ,
254+ } ,
255+ {
256+ name : "deadline" ,
257+ type : "uint256" ,
258+ } ,
259+ ] ,
260+ } ,
261+ primaryType : "Permit" ,
262+ domain : {
263+ name : policyToken . erc20Name ,
264+ version : policyToken . version ,
265+ chainId : client . chain . id ,
266+ verifyingContract : policyToken . address as Hex ,
267+ } ,
268+ message : {
269+ owner : account . address as Hex ,
270+ spender : paymasterAddress as Hex ,
271+ value : policyToken . maxTokenAmount ,
272+ nonce : ( await account . getAccountNonce ( ) ) + BigInt ( 1 ) ,
273+ deadline : BigInt ( 0xffffffffffffffffffffffffffffffff ) ,
274+ } ,
275+ } as const ;
276+
277+ erc20Context = {
278+ tokenAddress : policyToken . address ,
279+ permit : client . account ?. signTypedData ( typed_permit_data ) ,
280+ maxTokenAmount : policyToken . maxTokenAmount ,
281+ } ;
282+ }
283+
208284 const result = await ( client as AlchemySmartAccountClient ) . request ( {
209285 method : "alchemy_requestGasAndPaymasterAndData" ,
210286 params : [
@@ -214,11 +290,9 @@ export function alchemyGasAndPaymasterAndDataMiddleware(
214290 userOperation : userOp ,
215291 dummySignature : await account . getDummySignature ( ) ,
216292 overrides,
217- ...( policyToken
293+ ...( erc20Context
218294 ? {
219- erc20Context : {
220- tokenAddress : policyToken . address ,
221- } ,
295+ erc20Context : erc20Context ,
222296 }
223297 : { } ) ,
224298 } ,
0 commit comments