@@ -8,6 +8,8 @@ import { Web3Provider } from '@ethersproject/providers';
8
8
import { BigNumber } from '@ethersproject/bignumber' ;
9
9
import { TransactionParams } from '@metamask/transaction-controller' ;
10
10
import type { ChainId } from '@metamask/controller-utils' ;
11
+ import { HandlerType } from '@metamask/snaps-utils' ;
12
+ import type { SnapId } from '@metamask/snaps-sdk' ;
11
13
import {
12
14
fetchBridgeFeatureFlags ,
13
15
fetchBridgeQuotes ,
@@ -24,6 +26,7 @@ import {
24
26
BridgeFeatureFlagsKey ,
25
27
RequestStatus ,
26
28
type GenericQuoteRequest ,
29
+ type SolanaFees ,
27
30
} from '../../../../shared/types/bridge' ;
28
31
import { isValidQuoteRequest } from '../../../../shared/modules/bridge-utils/quote' ;
29
32
import { hasSufficientBalance } from '../../../../shared/modules/bridge-utils/balance' ;
@@ -170,7 +173,7 @@ export default class BridgeController extends StaticIntervalPollingController<Br
170
173
} ;
171
174
172
175
#hasSufficientBalance = async ( quoteRequest : GenericQuoteRequest ) => {
173
- const walletAddress = this . #getSelectedAccount ( ) . address ;
176
+ const walletAddress = this . #getMultichainSelectedAccount ( ) ? .address ;
174
177
const srcChainIdInHex = formatChainIdToHex ( quoteRequest . srcChainId ) ;
175
178
const provider = this . #getSelectedNetworkClient( ) ?. provider ;
176
179
const srcTokenAddressWithoutPrefix = formatAddressToString (
@@ -179,6 +182,7 @@ export default class BridgeController extends StaticIntervalPollingController<Br
179
182
180
183
return (
181
184
provider &&
185
+ walletAddress &&
182
186
srcTokenAddressWithoutPrefix &&
183
187
quoteRequest . srcTokenAmount &&
184
188
srcChainIdInHex &&
@@ -253,11 +257,12 @@ export default class BridgeController extends StaticIntervalPollingController<Br
253
257
) ;
254
258
255
259
const quotesWithL1GasFees = await this . #appendL1GasFees( quotes ) ;
260
+ const quotesWithSolanaFees = await this . #appendSolanaFees( quotes ) ;
256
261
257
262
this . update ( ( _state ) => {
258
263
_state . bridgeState = {
259
264
..._state . bridgeState ,
260
- quotes : quotesWithL1GasFees ,
265
+ quotes : quotesWithL1GasFees ?? quotesWithSolanaFees ?? quotes ,
261
266
quotesLoadingStatus : RequestStatus . FETCHED ,
262
267
} ;
263
268
} ) ;
@@ -309,45 +314,101 @@ export default class BridgeController extends StaticIntervalPollingController<Br
309
314
310
315
#appendL1GasFees = async (
311
316
quotes : QuoteResponse [ ] ,
312
- ) : Promise < ( QuoteResponse & L1GasFees ) [ ] > => {
317
+ ) : Promise < ( QuoteResponse & L1GasFees ) [ ] | undefined > => {
318
+ // Return undefined if some of the quotes are not for optimism or base
319
+ if (
320
+ quotes . some ( ( { quote } ) => {
321
+ const chainId = formatChainIdToCaip ( quote . srcChainId ) ;
322
+ return ! [ CHAIN_IDS . OPTIMISM , CHAIN_IDS . BASE ]
323
+ . map ( formatChainIdToCaip )
324
+ . includes ( chainId ) ;
325
+ } )
326
+ ) {
327
+ return undefined ;
328
+ }
329
+
313
330
return await Promise . all (
314
331
quotes . map ( async ( quoteResponse ) => {
315
332
const { quote, trade, approval } = quoteResponse ;
316
333
const chainId = add0x ( decimalToHex ( quote . srcChainId ) ) as ChainId ;
317
- if (
318
- [ CHAIN_IDS . OPTIMISM . toString ( ) , CHAIN_IDS . BASE . toString ( ) ] . includes (
319
- chainId ,
320
- )
321
- ) {
322
- const getTxParams = ( txData : TxData ) => ( {
323
- from : txData . from ,
324
- to : txData . to ,
325
- value : txData . value ,
326
- data : txData . data ,
327
- gasLimit : txData . gasLimit ?. toString ( ) ,
328
- } ) ;
329
- const approvalL1GasFees = approval
330
- ? await this . #getLayer1GasFee( {
331
- transactionParams : getTxParams ( approval ) ,
332
- chainId,
333
- } )
334
- : '0' ;
335
- const tradeL1GasFees = await this . #getLayer1GasFee( {
336
- transactionParams : getTxParams ( trade ) ,
337
- chainId,
338
- } ) ;
334
+
335
+ const getTxParams = ( txData : TxData ) => ( {
336
+ from : txData . from ,
337
+ to : txData . to ,
338
+ value : txData . value ,
339
+ data : txData . data ,
340
+ gasLimit : txData . gasLimit ?. toString ( ) ,
341
+ } ) ;
342
+ const approvalL1GasFees = approval
343
+ ? await this . #getLayer1GasFee( {
344
+ transactionParams : getTxParams ( approval ) ,
345
+ chainId,
346
+ } )
347
+ : '0' ;
348
+ const tradeL1GasFees = await this . #getLayer1GasFee( {
349
+ transactionParams : getTxParams ( trade ) ,
350
+ chainId,
351
+ } ) ;
352
+ return {
353
+ ...quoteResponse ,
354
+ l1GasFeesInHexWei : sumHexes ( approvalL1GasFees , tradeL1GasFees ) ,
355
+ } ;
356
+
357
+ return quoteResponse ;
358
+ } ) ,
359
+ ) ;
360
+ } ;
361
+
362
+ #appendSolanaFees = async (
363
+ quotes : QuoteResponse [ ] ,
364
+ ) : Promise < ( QuoteResponse & SolanaFees ) [ ] | undefined > => {
365
+ // Return undefined if some of the quotes are not for solana
366
+ if (
367
+ quotes . some ( ( { quote } ) => {
368
+ return (
369
+ formatChainIdToCaip ( quote . srcChainId ) !== MultichainNetworks . SOLANA
370
+ ) ;
371
+ } )
372
+ ) {
373
+ return undefined ;
374
+ }
375
+
376
+ return await Promise . all (
377
+ quotes . map ( async ( quoteResponse ) => {
378
+ const { trade } = quoteResponse ;
379
+ const selectedAccount = this . #getMultichainSelectedAccount( ) ;
380
+
381
+ if ( selectedAccount ?. metadata ?. snap ?. id && typeof trade === 'string' ) {
382
+ const { value : fees } = ( await this . messagingSystem . call (
383
+ 'SnapController:handleRequest' ,
384
+ {
385
+ snapId : selectedAccount . metadata . snap . id as SnapId ,
386
+ origin : 'metamask' ,
387
+ handler : HandlerType . OnRpcRequest ,
388
+ request : {
389
+ method : 'getFeeForTransaction' ,
390
+ params : {
391
+ transaction : trade ,
392
+ scope : selectedAccount . options . scope ,
393
+ } ,
394
+ } ,
395
+ } ,
396
+ ) ) as { value : string } ;
397
+
339
398
return {
340
399
...quoteResponse ,
341
- l1GasFeesInHexWei : sumHexes ( approvalL1GasFees , tradeL1GasFees ) ,
400
+ solanaFeesInLamports : fees ,
342
401
} ;
343
402
}
344
403
return quoteResponse ;
345
404
} ) ,
346
405
) ;
347
406
} ;
348
407
349
- #getSelectedAccount( ) {
350
- return this . messagingSystem . call ( 'AccountsController:getSelectedAccount' ) ;
408
+ #getMultichainSelectedAccount( ) {
409
+ return this . messagingSystem . call (
410
+ 'AccountsController:getSelectedMultichainAccount' ,
411
+ ) ; // ?? this.messagingSystem.call('AccountsController:getSelectedAccount')
351
412
}
352
413
353
414
#getSelectedNetworkClient( ) {
@@ -380,7 +441,8 @@ export default class BridgeController extends StaticIntervalPollingController<Br
380
441
381
442
const web3Provider = new Web3Provider ( provider ) ;
382
443
const contract = new Contract ( contractAddress , abiERC20 , web3Provider ) ;
383
- const { address : walletAddress } = this . #getSelectedAccount( ) ;
444
+ const { address : walletAddress } =
445
+ this . #getMultichainSelectedAccount( ) ?? { } ;
384
446
const allowance = await contract . allowance (
385
447
walletAddress ,
386
448
METABRIDGE_CHAIN_TO_ADDRESS_MAP [ chainId ] ,
0 commit comments