Skip to content

Commit

Permalink
Fix transaction simulation flicker (#446)
Browse files Browse the repository at this point in the history
  • Loading branch information
ChewingGlass authored Sep 12, 2023
1 parent 05e9c58 commit 207b517
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 49 deletions.
11 changes: 7 additions & 4 deletions src/hooks/useHntSolConvert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,15 @@ export function useHntSolConvert() {
}
}, [baseUrl])

const hasEnoughSol = useMemo(() => {
if (!hntBalance || !hntEstimate) return true
const hasEnoughHNTForSol = useMemo(() => {
if (!hntBalance || !hntEstimate) return false

if (hntBalance.lt(hntEstimate)) return true
return hntBalance.gt(hntEstimate)
}, [hntBalance, hntEstimate])

const hasEnoughSol = useMemo(() => {
return (solBalance || new BN(0)).gt(new BN(0.02 * LAMPORTS_PER_SOL))
}, [hntBalance, solBalance, hntEstimate])
}, [solBalance])

const {
result: hntSolConvertTransaction,
Expand Down Expand Up @@ -76,5 +78,6 @@ export function useHntSolConvert() {
hntEstimateLoading,
hntEstimateError,
hasEnoughSol,
hasEnoughHNTForSol,
}
}
89 changes: 44 additions & 45 deletions src/hooks/useSimulatedTransaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,13 @@ export function useSimulatedTransaction(
const { tokenAccounts } = useBalance()
const { connection, anchorProvider } = useSolana()
const { t: tr } = useTranslation()
const { hntSolConvertTransaction, hntEstimate, hasEnoughSol } =
useHntSolConvert()
const {
hntSolConvertTransaction,
hntEstimate,
hasEnoughSol,
hasEnoughHNTForSol,
hntEstimateLoading,
} = useHntSolConvert()

const [simulationError, setSimulationError] = useState(false)
const [insufficientFunds, setInsufficientFunds] = useState(false)
Expand Down Expand Up @@ -117,59 +122,50 @@ export function useSimulatedTransaction(
[connection, transaction],
)

const {
result: simulationAccounts,
loading: loadingAccounts,
// error: getAccountsErr,
} = useAsync(async () => {
if (!connection || !transaction) return []

const addressLookupTableAccounts: Array<AddressLookupTableAccount> = []
const { addressTableLookups } = transaction.message
if (addressTableLookups.length > 0) {
// eslint-disable-next-line no-restricted-syntax
for (const addressTableLookup of addressTableLookups) {
// eslint-disable-next-line no-await-in-loop
const result = await connection?.getAddressLookupTable(
addressTableLookup.accountKey,
)
if (result?.value) {
addressLookupTableAccounts.push(result?.value)
}
}
}
const accountKeys = transaction.message.getAccountKeys({
addressLookupTableAccounts,
})

return [
...new Set(
accountKeys.staticAccountKeys.concat(
accountKeys.accountKeysFromLookups
? // Only writable accounts will contribute to balance changes
accountKeys.accountKeysFromLookups.writable
: [],
),
),
]
}, [transaction, connection])

const { loading: loadingBal, result: estimatedBalanceChanges } =
useAsync(async () => {
if (
!connection ||
!transaction ||
!anchorProvider ||
!wallet ||
!simulationAccounts ||
!tokenAccounts
!tokenAccounts ||
hntEstimateLoading
)
return undefined

setSimulationError(false)
setInsufficientFunds(false)

try {
const addressLookupTableAccounts: Array<AddressLookupTableAccount> = []
const { addressTableLookups } = transaction.message
if (addressTableLookups.length > 0) {
// eslint-disable-next-line no-restricted-syntax
for (const addressTableLookup of addressTableLookups) {
// eslint-disable-next-line no-await-in-loop
const result = await connection?.getAddressLookupTable(
addressTableLookup.accountKey,
)
if (result?.value) {
addressLookupTableAccounts.push(result?.value)
}
}
}
const accountKeys = transaction.message.getAccountKeys({
addressLookupTableAccounts,
})

const simulationAccounts = [
...new Set(
accountKeys.staticAccountKeys.concat(
accountKeys.accountKeysFromLookups
? // Only writable accounts will contribute to balance changes
accountKeys.accountKeysFromLookups.writable
: [],
),
),
]
const { blockhash } = await connection?.getLatestBlockhash()
transaction.message.recentBlockhash = blockhash
const result = await connection?.simulateTransaction(transaction, {
Expand All @@ -184,7 +180,7 @@ export function useSimulatedTransaction(
console.warn('failed to simulate', result?.value.err)
console.warn(result?.value.logs?.join('\n'))
if (JSON.stringify(result?.value.err).includes('{"Custom":1}')) {
if (!hasEnoughSol) {
if (!hasEnoughSol && hasEnoughHNTForSol) {
await showHNTConversionAlert()
}
setInsufficientFunds(true)
Expand Down Expand Up @@ -306,7 +302,9 @@ export function useSimulatedTransaction(
nativeChange: Math.abs(toNumber(nativeChange, decimals)),
decimals,
mint: tokenMint,
symbol: tokenMetadata?.symbol,
symbol: tokenMint.equals(NATIVE_MINT)
? 'SOL'
: tokenMetadata?.symbol,
type,
} as BalanceChange
}
Expand All @@ -328,17 +326,18 @@ export function useSimulatedTransaction(
return undefined
}
}, [
simulationAccounts,
connection,
transaction,
tokenAccounts,
hasEnoughSol,
hasEnoughHNTForSol,
anchorProvider,
wallet,
hntEstimateLoading,
])

return {
loading: loadingBal || loadingAccounts || loadingFee,
loading: loadingBal || loadingFee,
simulationError,
insufficientFunds,
balanceChanges: estimatedBalanceChanges,
Expand Down

0 comments on commit 207b517

Please sign in to comment.