11import { PushChain } from '@pushchain/core' ;
2- import { PROGRESS_HOOK } from '@pushchain/core/src/lib/progress-hook/progress-hook.types' ;
2+ import { PROGRESS_HOOK , ProgressEvent } from '@pushchain/core/src/lib/progress-hook/progress-hook.types' ;
33import { usePushWalletContext } from './usePushWallet' ;
4- import { useEffect , useState } from 'react' ;
4+ import { useEffect , useState , useRef } from 'react' ;
55import { createGuardedPushChain } from '../helpers/txnAuthGuard' ;
6- import { useRef } from 'react' ;
76
87export const usePushChainClient = ( uid ?: string ) => {
98 const {
@@ -18,12 +17,51 @@ export const usePushChainClient = (uid?: string) => {
1817 isReadOnly,
1918 setIsReadOnly
2019 } = usePushWalletContext ( uid ) ;
20+
2121 const [ pushChain , setPushChain ] = useState < PushChain | null > ( null ) ;
2222 const [ error , setError ] = useState < Error | null > ( null ) ;
2323
24- const timeoutRef = useRef < ReturnType < typeof setTimeout > | null > ( null ) ;
24+ const MIN_VISIBLE_MS = 2000 ;
25+ const SUCCESS_HIDE_MS = 10000 ;
26+
27+ const queueRef = useRef < ProgressEvent [ ] > ( [ ] ) ;
28+ const lockRef = useRef ( false ) ;
29+
30+ const minTimerRef = useRef < ReturnType < typeof setTimeout > | null > ( null ) ;
31+ const successTimerRef = useRef < ReturnType < typeof setTimeout > | null > ( null ) ;
32+
33+ const clearProgressTimers = ( ) => {
34+ if ( minTimerRef . current ) {
35+ clearTimeout ( minTimerRef . current ) ;
36+ minTimerRef . current = null ;
37+ }
38+ if ( successTimerRef . current ) {
39+ clearTimeout ( successTimerRef . current ) ;
40+ successTimerRef . current = null ;
41+ }
42+ } ;
43+
44+ const showProgress = ( p : ProgressEvent ) => {
45+ clearProgressTimers ( ) ;
46+
47+ setProgress ( p ) ;
48+
49+ lockRef . current = true ;
50+ minTimerRef . current = setTimeout ( ( ) => {
51+ lockRef . current = false ;
52+ minTimerRef . current = null ;
53+
54+ if ( queueRef . current . length > 0 ) {
55+ const next = queueRef . current . shift ( ) ;
56+ if ( next ) showProgress ( next ) ;
57+ }
58+ } , MIN_VISIBLE_MS ) ;
59+
60+ if ( p . id === PROGRESS_HOOK . SEND_TX_99_01 ) {
61+ successTimerRef . current = setTimeout ( ( ) => setProgress ( null ) , SUCCESS_HIDE_MS ) ;
62+ }
63+ } ;
2564
26- // initialise Push Chain instance here and export that
2765 useEffect ( ( ) => {
2866 const initializePushChain = async ( ) => {
2967 if ( ! universalAccount ) {
@@ -40,41 +78,35 @@ export const usePushChainClient = (uid?: string) => {
4078 ] . includes ( universalAccount . chain ) ;
4179
4280 try {
43- const signerSkeleton = PushChain . utils . signer . construct (
44- universalAccount ,
45- {
46- signMessage : handleSignMessage ,
47- signAndSendTransaction : handleSignAndSendTransaction ,
48- signTypedData : isSolana ? undefined : handleSignTypedData ,
49- }
50- ) ;
51-
52- const universalSigner = await PushChain . utils . signer . toUniversal (
53- signerSkeleton
54- ) ;
81+ const signerSkeleton = PushChain . utils . signer . construct ( universalAccount , {
82+ signMessage : handleSignMessage ,
83+ signAndSendTransaction : handleSignAndSendTransaction ,
84+ signTypedData : isSolana ? undefined : handleSignTypedData ,
85+ } ) ;
86+
87+ const universalSigner = await PushChain . utils . signer . toUniversal ( signerSkeleton ) ;
5588
5689 const intializeProps = {
5790 network : config . network ,
58- progressHook : async ( progress : any ) => {
59- if ( timeoutRef . current ) {
60- clearTimeout ( timeoutRef . current ) ;
61- timeoutRef . current = null ;
62- }
63- setProgress ( progress ) ;
6491
65- if ( progress . id === PROGRESS_HOOK . SEND_TX_99_01 ) {
66- timeoutRef . current = setTimeout ( ( ) => setProgress ( null ) , 10000 ) ;
92+ progressHook : async ( incoming : ProgressEvent ) => {
93+ if ( ! lockRef . current ) {
94+ showProgress ( incoming ) ;
95+ } else {
96+ queueRef . current . push ( incoming ) ;
6797 }
6898 } ,
99+
69100 rpcUrls : config . chainConfig ?. rpcUrls ,
70101 blockExplorers : config . chainConfig ?. blockExplorers ,
71102 printTraces : config . chainConfig ?. printTraces ,
72- }
103+ } ;
73104
74105 if ( isReadOnly ) {
75106 const pushChainClient = await PushChain . initialize ( universalAccount , {
76107 network : config . network ,
77108 } ) ;
109+
78110 setPushChain (
79111 createGuardedPushChain (
80112 pushChainClient ,
@@ -91,21 +123,23 @@ export const usePushChainClient = (uid?: string) => {
91123 const pushChainClient = await PushChain . initialize ( universalSigner , intializeProps ) ;
92124 setPushChain ( pushChainClient ) ;
93125 }
94- setError ( null ) ;
95126
127+ setError ( null ) ;
96128 } catch ( err ) {
97129 console . log ( 'Error occured when initialising Push chain' , err ) ;
98- setError (
99- err instanceof Error
100- ? err
101- : new Error ( 'Failed to initialize PushChain' )
102- ) ;
130+ setError ( err instanceof Error ? err : new Error ( 'Failed to initialize PushChain' ) ) ;
103131 setPushChain ( null ) ;
104132 }
105133 } ;
106134
107135 initializePushChain ( ) ;
108- } , [ universalAccount , config ] ) ;
136+
137+ return ( ) => {
138+ clearProgressTimers ( ) ;
139+ queueRef . current = [ ] ;
140+ lockRef . current = false ;
141+ } ;
142+ } , [ universalAccount , config , isReadOnly ] ) ;
109143
110144 return {
111145 pushChainClient : pushChain ,
0 commit comments