Skip to content

Commit 830911c

Browse files
committed
put an error on the swap & bridge page indicating that the user doesn't have enough native even before going for quotes
1 parent 34fcb00 commit 830911c

File tree

8 files changed

+79
-2
lines changed

8 files changed

+79
-2
lines changed

src/controllers/swapAndBridge/swapAndBridge.ts

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1206,7 +1206,7 @@ export class SwapAndBridgeController extends EventEmitter implements ISwapAndBri
12061206
)
12071207
if (!native) return 0n
12081208

1209-
if (this.fromSelectedToken?.address !== ZeroAddress) return native.amount
1209+
if (this.fromSelectedToken?.address !== ZeroAddress || amount === 0n) return native.amount
12101210

12111211
// subtract the from amount from the portfolio available balance
12121212
if (amount > native.amount) return 0n
@@ -2465,6 +2465,33 @@ export class SwapAndBridgeController extends EventEmitter implements ISwapAndBri
24652465
})
24662466
}
24672467

2468+
// if the account cannot use other fee payment options than native
2469+
// and the account doesn't have any native,
2470+
// show an error
2471+
const accountNativeBalance = this.#accountNativeBalance(0n)
2472+
if (this.#selectedAccount.account && this.fromChainId && accountNativeBalance === 0n) {
2473+
const network = this.#networks.networks.find(
2474+
(net) => net.chainId === BigInt(this.fromChainId!)
2475+
)
2476+
if (network) {
2477+
const accountState =
2478+
this.#accounts.accountStates[this.#selectedAccount.account.addr][this.fromChainId]
2479+
if (accountState) {
2480+
const baseAcc = getBaseAccount(
2481+
this.#selectedAccount.account,
2482+
accountState,
2483+
this.#keystore.getAccountKeys(this.#selectedAccount.account),
2484+
network
2485+
)
2486+
if (!baseAcc.canPayWithTokens() && !baseAcc.canPayWithEOA()) {
2487+
errors.push({
2488+
title: `Insufficient ${network.nativeAssetSymbol} to cover the gas fees`
2489+
})
2490+
}
2491+
}
2492+
}
2493+
}
2494+
24682495
return errors
24692496
}
24702497

src/interfaces/account.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ export interface AccountOnchainState {
5454
isSmarterEoa: boolean
5555
delegatedContract: Hex | null
5656
delegatedContractName: 'AMBIRE' | 'METAMASK' | 'UNKNOWN' | null
57+
hasEoaWithNative: boolean
5758
}
5859

5960
export type AccountStates = {

src/libs/account/BaseAccount.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,16 @@ export abstract class BaseAccount {
8686
*/
8787
abstract getNonceId(): string
8888

89+
/**
90+
* Can the account pay with tokens the transaction fee
91+
*/
92+
abstract canPayWithTokens(): boolean
93+
94+
/**
95+
* Can the account pay with tokens the transaction fee
96+
*/
97+
abstract canPayWithEOA(): boolean
98+
8999
// this is specific for v2 accounts, hardcoding a false for all else
90100
shouldIncludeActivatorCall(broadcastOption: string) {
91101
return false

src/libs/account/EOA.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,4 +117,12 @@ export class EOA extends BaseAccount {
117117
// EOAs have only an execution layer nonce
118118
return this.accountState.eoaNonce!.toString()
119119
}
120+
121+
canPayWithTokens(): boolean {
122+
return false
123+
}
124+
125+
canPayWithEOA(): boolean {
126+
return false
127+
}
120128
}

src/libs/account/EOA7702.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { Interface } from 'ethers'
33
import AmbireAccount from '../../../contracts/compiled/AmbireAccount.json'
44
import AmbireAccount7702 from '../../../contracts/compiled/AmbireAccount7702.json'
55
import { Hex } from '../../interfaces/hex'
6+
import { has7702 } from '../7702/7702'
67
import { AccountOp, getSignableCalls } from '../accountOp/accountOp'
78
import { BROADCAST_OPTIONS } from '../broadcast/broadcast'
89
import {
@@ -197,4 +198,12 @@ export class EOA7702 extends BaseAccount {
197198
// 7702 accounts have an execution layer nonce and an entry point nonce
198199
return `${this.accountState.eoaNonce!.toString()}-${this.accountState.erc4337Nonce.toString()}`
199200
}
201+
202+
canPayWithTokens(): boolean {
203+
return has7702(this.network) && this.network.erc4337.hasPaymaster
204+
}
205+
206+
canPayWithEOA(): boolean {
207+
return false
208+
}
200209
}

src/libs/account/V1.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,4 +98,12 @@ export class V1 extends BaseAccount {
9898
// v1 accounts can only have an ambire smart contract nonce
9999
return this.accountState.nonce.toString()
100100
}
101+
102+
canPayWithTokens(): boolean {
103+
return this.network.hasRelayer
104+
}
105+
106+
canPayWithEOA(): boolean {
107+
return this.accountState.hasEoaWithNative
108+
}
101109
}

src/libs/account/V2.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,4 +173,16 @@ export class V2 extends BaseAccount {
173173
// v2 accounts have two nonces: ambire smart account & entry point nonce
174174
return `${this.accountState.nonce.toString()}-${this.accountState.erc4337Nonce.toString()}`
175175
}
176+
177+
canPayWithTokens(): boolean {
178+
if (this.network.erc4337.enabled) {
179+
return this.network.erc4337.hasPaymaster
180+
}
181+
182+
return this.network.hasRelayer
183+
}
184+
185+
canPayWithEOA(): boolean {
186+
return this.accountState.hasEoaWithNative
187+
}
176188
}

src/libs/accountState/accountState.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ export async function getAccountState(
7373
getEOAsCode(eoas)
7474
])
7575

76+
const hasEoaWithNative = !!accountStateResult.find((res: any) => res.isEOA && res.balance > 0)
7677
const result: AccountOnchainState[] = accountStateResult.map((accResult: any, index: number) => {
7778
const associatedKeys = accResult.associatedKeyPrivileges.map(
7879
(privilege: string, keyIndex: number) => {
@@ -130,7 +131,8 @@ export async function getAccountState(
130131
account.associatedKeys.length > 0 && accResult.associatedKeyPrivileges.length === 0,
131132
isSmarterEoa,
132133
delegatedContract,
133-
delegatedContractName
134+
delegatedContractName,
135+
hasEoaWithNative
134136
}
135137
})
136138

0 commit comments

Comments
 (0)