@@ -91,7 +91,7 @@ export class QueryBase implements QueryInterface {
9191 transport,
9292 } = options ;
9393
94- const tx = await populateV3Relay ( this . spokePool , deposit , relayer ) ;
94+ const tx = await this . getUnsignedTxFromDeposit ( deposit , relayer ) ;
9595 const {
9696 nativeGasCost,
9797 tokenGasCost,
@@ -114,6 +114,59 @@ export class QueryBase implements QueryInterface {
114114 } ;
115115 }
116116
117+ /**
118+ * @notice Return ethers.PopulatedTransaction for a fill based on input deposit args
119+ * @param deposit
120+ * @param relayer Sender of PopulatedTransaction
121+ * @returns PopulatedTransaction
122+ */
123+ getUnsignedTxFromDeposit (
124+ deposit : Deposit ,
125+ relayer = DEFAULT_SIMULATED_RELAYER_ADDRESS
126+ ) : Promise < PopulatedTransaction > {
127+ return populateV3Relay ( this . spokePool , deposit , relayer ) ;
128+ }
129+
130+ /**
131+ * @notice Return the gas cost of a simulated transaction
132+ * @param deposit
133+ * @param relayer Sender of PopulatedTransaction
134+ * @returns Estimated gas cost based on ethers.VoidSigner's gas estimation
135+ */
136+ async getNativeGasCost ( deposit : Deposit , relayer = DEFAULT_SIMULATED_RELAYER_ADDRESS ) : Promise < BigNumber > {
137+ const unsignedTx = await this . getUnsignedTxFromDeposit ( deposit , relayer ) ;
138+ const voidSigner = new VoidSigner ( relayer , this . provider ) ;
139+ return voidSigner . estimateGas ( unsignedTx ) ;
140+ }
141+
142+ /**
143+ * @notice Return L1 data fee for OP stack L2 transaction, which is based on L2 calldata.
144+ * @dev https://docs.optimism.io/stack/transactions/fees#l1-data-fee
145+ * @param unsignedTx L2 transaction that you want L1 data fee for
146+ * @param relayer Sender of unsignedTx
147+ * @param options Specify gas units to avoid additional gas estimation call and multiplier for L1 data fee
148+ * @returns BigNumber L1 data fee in gas units
149+ */
150+ async getOpStackL1DataFee (
151+ unsignedTx : PopulatedTransaction ,
152+ relayer = DEFAULT_SIMULATED_RELAYER_ADDRESS ,
153+ options : Partial < {
154+ opStackL2GasUnits : BigNumberish ;
155+ opStackL1DataFeeMultiplier : BigNumber ;
156+ } >
157+ ) : Promise < BigNumber > {
158+ const { opStackL2GasUnits, opStackL1DataFeeMultiplier = toBNWei ( "1" ) } = options || { } ;
159+ const { chainId } = await this . provider . getNetwork ( ) ;
160+ assert ( isOptimismL2Provider ( this . provider ) , `Unexpected provider for chain ID ${ chainId } .` ) ;
161+ const voidSigner = new VoidSigner ( relayer , this . provider ) ;
162+ const populatedTransaction = await voidSigner . populateTransaction ( {
163+ ...unsignedTx ,
164+ gasLimit : opStackL2GasUnits , // prevents additional gas estimation call
165+ } ) ;
166+ const l1DataFee = await ( this . provider as L2Provider < providers . Provider > ) . estimateL1GasCost ( populatedTransaction ) ;
167+ return l1DataFee . mul ( opStackL1DataFeeMultiplier ) . div ( fixedPointAdjustment ) ;
168+ }
169+
117170 /**
118171 * Estimates the total gas cost required to submit an unsigned (populated) transaction on-chain.
119172 * @param unsignedTx The unsigned transaction that this function will estimate.
@@ -164,13 +217,10 @@ export class QueryBase implements QueryInterface {
164217 // OP stack is a special case; gas cost is computed by the SDK, without having to query price.
165218 let opStackL1GasCost : BigNumber | undefined ;
166219 if ( chainIsOPStack ( chainId ) ) {
167- assert ( isOptimismL2Provider ( provider ) , `Unexpected provider for chain ID ${ chainId } .` ) ;
168- const populatedTransaction = await voidSigner . populateTransaction ( {
169- ...unsignedTx ,
170- gasLimit : nativeGasCost , // prevents additional gas estimation call
220+ opStackL1GasCost = await this . getOpStackL1DataFee ( unsignedTx , senderAddress , {
221+ opStackL2GasUnits : nativeGasCost ,
222+ opStackL1DataFeeMultiplier : opStackL1GasCostMultiplier ,
171223 } ) ;
172- const l1GasCost = await ( provider as L2Provider < providers . Provider > ) . estimateL1GasCost ( populatedTransaction ) ;
173- opStackL1GasCost = l1GasCost . mul ( opStackL1GasCostMultiplier ) . div ( fixedPointAdjustment ) ;
174224 const l2GasCost = nativeGasCost . mul ( gasPrice ) ;
175225 tokenGasCost = opStackL1GasCost . add ( l2GasCost ) ;
176226 } else {
0 commit comments