11import { type Address , type Chain , createWalletClient , custom , type Hash , http , type RpcSchema as RpcSchemaGeneric , type SendTransactionParameters , type Transport , type WalletClient } from "viem" ;
2+ import type { TransactionRequestEIP712 } from "viem/chains" ;
23
34import { createZksyncSessionClient , type ZksyncSsoSessionClient } from "../client/index.js" ;
45import type { Communicator } from "../communicator/index.js" ;
6+ import { type CustomPaymasterHandler , getTransactionWithPaymasterData } from "../paymaster/index.js" ;
57import { StorageItem } from "../utils/storage.js" ;
68import type { AppMetadata , RequestArguments } from "./interface.js" ;
79import type { AuthServerRpcSchema , ExtractParams , ExtractReturnType , Method , RPCRequestMessage , RPCResponseMessage , RpcSchema } from "./rpc.js" ;
@@ -38,6 +40,7 @@ type SignerConstructorParams = {
3840 chains : readonly Chain [ ] ;
3941 transports ?: Record < number , Transport > ;
4042 session ?: ( ) => SessionPreferences | Promise < SessionPreferences > ;
43+ paymasterHandler ?: CustomPaymasterHandler ;
4144} ;
4245
4346type ChainsInfo = ExtractReturnType < "eth_requestAccounts" , AuthServerRpcSchema > [ "chainsInfo" ] ;
@@ -49,12 +52,13 @@ export class Signer implements SignerInterface {
4952 private readonly chains : readonly Chain [ ] ;
5053 private readonly transports : Record < number , Transport > = { } ;
5154 private readonly sessionParameters ?: ( ) => ( SessionPreferences | Promise < SessionPreferences > ) ;
55+ private readonly paymasterHandler ?: CustomPaymasterHandler ;
5256
5357 private _account : StorageItem < Account | null > ;
5458 private _chainsInfo = new StorageItem < ChainsInfo > ( StorageItem . scopedStorageKey ( "chainsInfo" ) , [ ] ) ;
5559 private client : { instance : ZksyncSsoSessionClient ; type : "session" } | { instance : WalletClient ; type : "auth-server" } | undefined ;
5660
57- constructor ( { metadata, communicator, updateListener, session, chains, transports } : SignerConstructorParams ) {
61+ constructor ( { metadata, communicator, updateListener, session, chains, transports, paymasterHandler } : SignerConstructorParams ) {
5862 if ( ! chains . length ) throw new Error ( "At least one chain must be included in the config" ) ;
5963
6064 this . getMetadata = metadata ;
@@ -63,6 +67,7 @@ export class Signer implements SignerInterface {
6367 this . sessionParameters = session ;
6468 this . chains = chains ;
6569 this . transports = transports || { } ;
70+ this . paymasterHandler = paymasterHandler ;
6671
6772 this . _account = new StorageItem < Account | null > ( StorageItem . scopedStorageKey ( "account" ) , null , {
6873 onChange : ( newValue ) => {
@@ -136,6 +141,7 @@ export class Signer implements SignerInterface {
136141 contracts : chainInfo . contracts ,
137142 chain,
138143 transport : this . transports [ chain . id ] || http ( ) ,
144+ paymasterHandler : this . paymasterHandler ,
139145 } ) ,
140146 } ;
141147 } else {
@@ -266,6 +272,23 @@ export class Signer implements SignerInterface {
266272 // Open popup immediately to make sure popup won't be blocked by Safari
267273 await this . communicator . ready ( ) ;
268274
275+ if ( request . method === "eth_sendTransaction" ) {
276+ const params = request . params ! [ 0 ] as TransactionRequestEIP712 ;
277+ if ( params ) {
278+ /* eslint-disable @typescript-eslint/no-unused-vars */
279+ const { chainId : _ , ...transaction } = await getTransactionWithPaymasterData (
280+ this . chain . id ,
281+ params . from ,
282+ params ,
283+ this . paymasterHandler ,
284+ ) ;
285+ request = {
286+ method : request . method ,
287+ params : [ transaction ] as ExtractParams < TMethod , TSchema > ,
288+ } ;
289+ }
290+ }
291+
269292 const message = this . createRequestMessage < TMethod , TSchema > ( {
270293 action : request ,
271294 chainId : this . chain . id ,
0 commit comments