11import {
2- ExternalProvider , JsonRpcProvider , TransactionRequest , Web3Provider ,
2+ ExternalProvider , JsonRpcProvider , JsonRpcSigner , TransactionRequest , Web3Provider ,
33} from '@ethersproject/providers' ;
4- import { BigNumber } from 'ethers' ;
4+ import { BigNumber , BigNumberish } from 'ethers' ;
55import { getEip155ChainId , getNonce , getSignedMetaTransactions } from './walletHelpers' ;
66import { MetaTransaction , RelayerTransactionStatus } from './types' ;
77import { JsonRpcError , RpcErrorCode } from './JsonRpcError' ;
@@ -22,6 +22,51 @@ export type EthSendTransactionParams = {
2222 params : Array < any > ;
2323} ;
2424
25+ const getMetaTransactions = async (
26+ metaTransaction : MetaTransaction ,
27+ nonce : BigNumberish ,
28+ chainId : BigNumber ,
29+ walletAddress : string ,
30+ signer : JsonRpcSigner ,
31+ relayerClient : RelayerClient ,
32+ ) : Promise < MetaTransaction [ ] > => {
33+ // NOTE: We sign the transaction before getting the fee options because
34+ // accurate estimation of a transaction gas cost is only possible if the smart
35+ // wallet contract can actually execute it (in a simulated environment) - and
36+ // it can only execute signed transactions.
37+ const signedTransaction = await getSignedMetaTransactions (
38+ [ metaTransaction ] ,
39+ nonce ,
40+ chainId ,
41+ walletAddress ,
42+ signer ,
43+ ) ;
44+
45+ // TODO: ID-698 Add support for non-native gas payments (e.g ERC20, feeTransaction initialisation must change)
46+
47+ // NOTE: "Fee Options" represent the multiple ways we could pay for the gas
48+ // used in this transaction. Each fee option has a "recipientAddress" we
49+ // should transfer the payment to, an amount and a currency. We choose one
50+ // option and build a transaction that sends the expected currency amount for
51+ // that option to the specified address.
52+ const feeOptions = await relayerClient . imGetFeeOptions ( walletAddress , signedTransaction ) ;
53+ const imxFeeOption = feeOptions . find ( ( feeOption ) => feeOption . tokenSymbol === 'IMX' ) ;
54+ if ( ! imxFeeOption ) {
55+ throw new Error ( 'Failed to retrieve fees for IMX token' ) ;
56+ }
57+
58+ const feeMetaTransaction : MetaTransaction = {
59+ nonce,
60+ to : imxFeeOption . recipientAddress ,
61+ value : imxFeeOption . tokenPrice ,
62+ revertOnError : true ,
63+ } ;
64+ if ( BigNumber . from ( feeMetaTransaction . value ) . isZero ( ) ) {
65+ return [ metaTransaction ] ;
66+ }
67+ return [ metaTransaction , feeMetaTransaction ] ;
68+ } ;
69+
2570export const sendTransaction = ( {
2671 params,
2772 magicProvider,
@@ -50,49 +95,26 @@ export const sendTransaction = ({
5095 revertOnError : true ,
5196 } ;
5297
53- // NOTE: We sign the transaction before getting the fee options because
54- // accurate estimation of a transaction gas cost is only possible if the smart
55- // wallet contract can actually execute it (in a simulated environment) - and
56- // it can only execute signed transactions.
57- const signedTransaction = await getSignedMetaTransactions (
58- [ metaTransaction ] ,
98+ const metaTransactions = await getMetaTransactions (
99+ metaTransaction ,
59100 nonce ,
60101 chainIdBigNumber ,
61102 user . zkEvm . ethAddress ,
62103 signer ,
104+ relayerClient ,
63105 ) ;
64106
65- // TODO: ID-698 Add support for non-native gas payments (e.g ERC20, feeTransaction initialisation must change)
66-
67- // NOTE: "Fee Options" represent the multiple ways we could pay for the gas
68- // used in this transaction. Each fee option has a "recipientAddress" we
69- // should transfer the payment to, an amount and a currency. We choose one
70- // option and build a transaction that sends the expected currency amount for
71- // that option to the specified address.
72- const feeOptions = await relayerClient . imGetFeeOptions ( user . zkEvm . ethAddress , signedTransaction ) ;
73- const imxFeeOption = feeOptions . find ( ( feeOption ) => feeOption . tokenSymbol === 'IMX' ) ;
74- if ( ! imxFeeOption ) {
75- throw new Error ( 'Failed to retrieve fees for IMX token' ) ;
76- }
77-
78- const feeMetaTransaction : MetaTransaction = {
79- nonce,
80- to : imxFeeOption . recipientAddress ,
81- value : imxFeeOption . tokenPrice ,
82- revertOnError : true ,
83- } ;
84-
85107 await guardianClient . validateEVMTransaction ( {
86108 chainId : getEip155ChainId ( chainId ) ,
87109 nonce : convertBigNumberishToString ( nonce ) ,
88110 user,
89- metaTransactions : [ metaTransaction , feeMetaTransaction ] ,
111+ metaTransactions,
90112 } ) ;
91113
92114 // NOTE: We sign again because we now are adding the fee transaction, so the
93115 // whole payload is different and needs a new signature.
94116 const signedTransactions = await getSignedMetaTransactions (
95- [ metaTransaction , feeMetaTransaction ] ,
117+ metaTransactions ,
96118 nonce ,
97119 chainIdBigNumber ,
98120 user . zkEvm . ethAddress ,
0 commit comments