1- import type { UnsignedTransaction } from 'ethers' ;
1+ import type { BigNumberish , UnsignedTransaction } from 'ethers' ;
22import { ethers } from 'ethers' ;
3+ import {
4+ EIP712Signer ,
5+ utils as zkSyncUtils ,
6+ Provider as ZksProvider ,
7+ } from 'zksync-ethers' ;
38import type { Emitter } from 'nanoevents' ;
49import { createNanoEvents } from 'nanoevents' ;
510import { Store } from 'store-unit' ;
@@ -28,7 +33,10 @@ import {
2833 INTERNAL_ORIGIN_SYMBOL ,
2934} from 'src/background/constants' ;
3035import { networksStore } from 'src/modules/networks/networks-store.background' ;
31- import type { IncomingTransaction } from 'src/modules/ethereum/types/IncomingTransaction' ;
36+ import type {
37+ IncomingTransactionAA ,
38+ IncomingTransactionWithChainId ,
39+ } from 'src/modules/ethereum/types/IncomingTransaction' ;
3240import { prepareTransaction } from 'src/modules/ethereum/transactions/prepareTransaction' ;
3341import type { Chain } from 'src/modules/networks/Chain' ;
3442import { createChain } from 'src/modules/networks/Chain' ;
@@ -69,6 +77,8 @@ import { backgroundGetBestKnownTransactionCount } from 'src/modules/ethereum/tra
6977import { toCustomNetworkId } from 'src/modules/ethereum/chains/helpers' ;
7078import { normalizeTransactionChainId } from 'src/modules/ethereum/transactions/normalizeTransactionChainId' ;
7179import type { ChainId } from 'src/modules/ethereum/transactions/ChainId' ;
80+ import { FEATURE_PAYMASTER_ENABLED } from 'src/env/config' ;
81+ import { createTypedData } from 'src/modules/ethereum/account-abstraction/createTypedData' ;
7282import type { DaylightEventParams , ScreenViewParams } from '../events' ;
7383import { emitter } from '../events' ;
7484import type { Credentials , SessionCredentials } from '../account/Credentials' ;
@@ -92,7 +102,11 @@ import {
92102 ReadonlyAccountContainer ,
93103} from './model/AccountContainer' ;
94104
95- async function prepareNonce < T extends { nonce ?: number ; from ?: string } > (
105+ if ( FEATURE_PAYMASTER_ENABLED ) {
106+ Object . assign ( globalThis , { EIP712Signer, zkSyncUtils } ) ;
107+ }
108+
109+ async function prepareNonce < T extends { nonce ?: BigNumberish ; from ?: string } > (
96110 transaction : T ,
97111 networks : Networks ,
98112 chain : string
@@ -899,10 +913,26 @@ export class Wallet {
899913 this . emitter . emit ( 'chainChanged' , chain , origin ) ;
900914 }
901915
916+ /** A helper for interpretation in UI */
917+ async uiGetEip712Transaction ( {
918+ params : { transaction } ,
919+ context,
920+ } : WalletMethodParams < { transaction : IncomingTransactionWithChainId } > ) {
921+ this . verifyInternalOrigin ( context ) ;
922+
923+ const prepared = prepareTransaction ( transaction ) ;
924+ const typedData = createTypedData ( prepared ) ;
925+ return typedData ;
926+ }
927+
902928 private async getProvider ( chainId : ChainId ) {
903929 const networks = await networksStore . loadNetworksWithChainId ( chainId ) ;
904930 const nodeUrl = networks . getRpcUrlInternal ( networks . getChainById ( chainId ) ) ;
905- return new ethers . providers . JsonRpcProvider ( nodeUrl ) ;
931+ if ( FEATURE_PAYMASTER_ENABLED ) {
932+ return new ZksProvider ( nodeUrl ) ;
933+ } else {
934+ return new ethers . providers . JsonRpcProvider ( nodeUrl ) ;
935+ }
906936 }
907937
908938 private async getSigner ( chainId : ChainId ) {
@@ -927,7 +957,7 @@ export class Wallet {
927957 context,
928958 ...transactionContextParams
929959 } : {
930- transaction : IncomingTransaction ;
960+ transaction : IncomingTransactionAA ;
931961 context : Partial < ChannelContext > | undefined ;
932962 } & TransactionContextParams ) : Promise < ethers . providers . TransactionResponse > {
933963 this . verifyInternalOrigin ( context ) ;
@@ -968,31 +998,66 @@ export class Wallet {
968998 invariant ( chainId , 'Must resolve chainId first' ) ;
969999
9701000 const networks = await networksStore . loadNetworksWithChainId ( chainId ) ;
971- const signer = await this . getSigner ( chainId ) ;
9721001 const prepared = prepareTransaction ( incomingTransaction ) ;
9731002 const txWithFee = await prepareGasAndNetworkFee ( prepared , networks ) ;
9741003 const transaction = await prepareNonce ( txWithFee , networks , chain ) ;
9751004
976- try {
977- const transactionResponse = await signer . sendTransaction ( {
978- ...transaction ,
979- type : transaction . type || undefined , // to exclude null
980- } ) ;
981- const safeTx = removeSignature ( transactionResponse ) ;
982- emitter . emit ( 'transactionSent' , {
983- transaction : safeTx ,
984- ...transactionContextParams ,
985- } ) ;
986- return safeTx ;
987- } catch ( error ) {
988- throw getEthersError ( error ) ;
1005+ const paymasterEligible =
1006+ FEATURE_PAYMASTER_ENABLED &&
1007+ Boolean ( transaction . customData ?. paymasterParams ) ;
1008+
1009+ if ( paymasterEligible ) {
1010+ console . log ( 'paymasterEligible' , { transaction } ) ;
1011+ try {
1012+ const { chainId } = transaction ;
1013+ invariant ( chainId , 'ChainId missing from TransactionRequest' ) ;
1014+ const typedData = createTypedData ( transaction ) ;
1015+ console . log ( 'will sign typedData:' , { typedData } ) ;
1016+ const signature = await this . signTypedData_v4 ( {
1017+ context,
1018+ params : { typedData, ...transactionContextParams } ,
1019+ } ) ;
1020+ console . log ( 'will serialize transaction + signature' , {
1021+ transaction,
1022+ signature,
1023+ } ) ;
1024+ const rawTransaction = zkSyncUtils . serialize ( {
1025+ ...transaction ,
1026+ customData : { ...transaction . customData , customSignature : signature } ,
1027+ } ) ;
1028+
1029+ console . log ( { rawTransaction } ) ;
1030+ return await this . sendSignedTransaction ( {
1031+ context,
1032+ params : { serialized : rawTransaction , ...transactionContextParams } ,
1033+ } ) ;
1034+ } catch ( error ) {
1035+ console . log ( 'paymaster tx error' , error ) ;
1036+ throw getEthersError ( error ) ;
1037+ }
1038+ } else {
1039+ try {
1040+ const signer = await this . getSigner ( chainId ) ;
1041+ const transactionResponse = await signer . sendTransaction ( {
1042+ ...transaction ,
1043+ type : transaction . type || undefined , // to exclude null
1044+ } ) ;
1045+ const safeTx = removeSignature ( transactionResponse ) ;
1046+ emitter . emit ( 'transactionSent' , {
1047+ transaction : safeTx ,
1048+ ...transactionContextParams ,
1049+ } ) ;
1050+ return safeTx ;
1051+ } catch ( error ) {
1052+ throw getEthersError ( error ) ;
1053+ }
9891054 }
9901055 }
9911056
9921057 async signAndSendTransaction ( {
9931058 params,
9941059 context,
995- } : WalletMethodParams < [ IncomingTransaction , TransactionContextParams ] > ) {
1060+ } : WalletMethodParams < [ IncomingTransactionAA , TransactionContextParams ] > ) {
9961061 this . verifyInternalOrigin ( context ) ;
9971062 this . ensureStringOrigin ( context ) ;
9981063 const [ transaction , transactionContextParams ] = params ;
0 commit comments