@@ -11,23 +11,63 @@ import { ArrowLeftIcon } from "../../icons/ArrowLeftIcon";
1111import { StepContentProps } from "../common" ;
1212import { usePrevious } from "../../errors/usePrevious" ;
1313import { WithdrawGasBalanceButton } from "./WithdrawGasBalanceButton" ;
14+ import { useAllowance } from "./useAllowance" ;
15+ import { useRequestAllowance } from "./useRequestAllowance" ;
16+ import { Paymaster } from "../../getPaymaster" ;
1417
1518export type Props = StepContentProps & {
1619 userAddress : Hex ;
20+ paymaster : Paymaster ;
1721} ;
1822
19- export function GasBalance ( { isActive, isExpanded, isFocused, setFocused, userAddress } : Props ) {
23+ export function GasBalance ( { isActive, isExpanded, isFocused, setFocused, userAddress, paymaster } : Props ) {
2024 const queryClient = useQueryClient ( ) ;
2125 const balance = useShowQueryError ( useBalance ( userAddress ) ) ;
2226 const prevBalance = usePrevious ( balance . data || 0n ) ;
2327
28+ const allowance = useShowQueryError ( useAllowance ( userAddress ) ) ;
29+ const prevAllowance = usePrevious ( allowance . data || 0n ) ;
30+ const requestAllowance = useRequestAllowance ( ) ;
31+
2432 useEffect ( ( ) => {
2533 if ( balance . data != null && prevBalance === 0n && balance . data > 0n ) {
2634 queryClient . invalidateQueries ( { queryKey : [ "getPrerequisites" ] } ) ;
2735 setFocused ( false ) ;
2836 }
2937 } , [ balance . data , prevBalance , setFocused , queryClient , userAddress ] ) ;
3038
39+ useEffect ( ( ) => {
40+ if ( allowance . data != null && prevAllowance === 0n && allowance . data > 0n ) {
41+ queryClient . invalidateQueries ( { queryKey : [ "getPrerequisites" ] } ) ;
42+ setFocused ( false ) ;
43+ }
44+ } , [ allowance . data , prevAllowance , setFocused , queryClient , userAddress ] ) ;
45+
46+ const gasBalance = balance . data != null && allowance . data != null ? balance . data + allowance . data : null ;
47+ useEffect ( ( ) => {
48+ if ( ! isActive ) return ;
49+ if ( ! paymaster . canSponsor ) return ;
50+ if ( gasBalance !== 0n ) return ;
51+ if ( requestAllowance . status !== "idle" ) return ;
52+
53+ // There seems to be a tanstack-query bug(?) where multiple simultaneous renders loses
54+ // state between the two mutations. They're not treated as shared state but rather
55+ // individual mutations, even though the keys match. And the one we want the status of
56+ // seems to stay pending. This is sorta resolved by triggering this after a timeout.
57+ const timer = setTimeout ( ( ) => {
58+ console . log ( "no funds, requesting allowance" ) ;
59+ requestAllowance . mutate ( userAddress , {
60+ onSuccess ( data ) {
61+ console . log ( "got allowance" , data ) ;
62+ } ,
63+ onError ( error ) {
64+ console . log ( "failed to get allowance" , error ) ;
65+ } ,
66+ } ) ;
67+ } ) ;
68+ return ( ) => clearTimeout ( timer ) ;
69+ } , [ isActive , paymaster . canSponsor , gasBalance , requestAllowance , userAddress ] ) ;
70+
3171 if ( isFocused ) {
3272 return (
3373 < div >
@@ -52,7 +92,7 @@ export function GasBalance({ isActive, isExpanded, isFocused, setFocused, userAd
5292 < div >
5393 < div > Gas balance</ div >
5494 < div className = "font-mono text-white" >
55- { balance . data != null ? < Balance wei = { balance . data } /> : < PendingIcon className = "text-sm" /> }
95+ { gasBalance != null ? < Balance wei = { gasBalance } /> : < PendingIcon className = "text-sm" /> }
5696 </ div >
5797 </ div >
5898
@@ -61,7 +101,9 @@ export function GasBalance({ isActive, isExpanded, isFocused, setFocused, userAd
61101 variant = { isActive ? "primary" : "tertiary" }
62102 className = "flex-shrink-0 text-sm p-1 w-28"
63103 autoFocus = { isActive || isExpanded }
64- pending = { balance . status === "pending" }
104+ pending = {
105+ balance . status === "pending" || allowance . status === "pending" || requestAllowance . status === "pending"
106+ }
65107 onClick = { ( ) => setFocused ( true ) }
66108 >
67109 Top up
@@ -70,7 +112,22 @@ export function GasBalance({ isActive, isExpanded, isFocused, setFocused, userAd
70112 < WithdrawGasBalanceButton userAddress = { userAddress } />
71113 </ div >
72114 </ div >
73- { isExpanded ? < p className = "text-sm" > Your gas balance is used to pay for onchain computation.</ p > : null }
115+ { isExpanded ? (
116+ < div className = "text-sm space-y-2" >
117+ < p > Your gas balance is used to pay for onchain computation.</ p >
118+ < p >
119+ You have{ " " }
120+ < span className = "font-mono" >
121+ { balance . data != null ? < Balance wei = { balance . data } /> : < PendingIcon className = "text-sm" /> }
122+ </ span > { " " }
123+ in gas deposits and{ " " }
124+ < span className = "font-mono" >
125+ { allowance . data != null ? < Balance wei = { allowance . data } /> : < PendingIcon className = "text-sm" /> }
126+ </ span > { " " }
127+ in gas grants.
128+ </ p >
129+ </ div >
130+ ) : null }
74131 </ div >
75132 ) ;
76133}
0 commit comments