@@ -21,6 +21,7 @@ import walletServiceManager, {
2121 WalletConnection ,
2222 TokenBalance ,
2323} from '../services/walletService' ;
24+ import { useTransactionQueueStore } from '../store/transactionQueueStore' ;
2425
2526interface RouteParams {
2627 subscriptionId ?: string ;
@@ -48,6 +49,17 @@ const CryptoPaymentScreen: React.FC = () => {
4849 const [ availableTokens , setAvailableTokens ] = useState < TokenBalance [ ] > ( [ ] ) ;
4950 const [ connection , setConnection ] = useState < WalletConnection | null > ( null ) ;
5051
52+ const isOnline = useTransactionQueueStore ( ( state ) => state . isOnline ) ;
53+ const isQueueProcessing = useTransactionQueueStore ( ( state ) => state . isProcessing ) ;
54+ const queuedTransactions = useTransactionQueueStore ( ( state ) => state . queuedTransactions ) ;
55+ const executeOrQueueTransaction = useTransactionQueueStore (
56+ ( state ) => state . executeOrQueueTransaction
57+ ) ;
58+
59+ const pendingCount = queuedTransactions . filter (
60+ ( tx ) => tx . status === 'pending' || tx . status === 'processing'
61+ ) . length ;
62+
5163 useEffect ( ( ) => {
5264 loadWalletData ( ) ;
5365 } , [ ] ) ;
@@ -148,31 +160,35 @@ const CryptoPaymentScreen: React.FC = () => {
148160
149161 try {
150162 setIsLoading ( true ) ;
151- let streamId : string ;
152- let txHash : string | undefined ;
153-
154- if ( selectedProtocol === 'superfluid' ) {
155- const result = await walletServiceManager . createSuperfluidStream (
156- selectedToken ,
157- amount ,
158- recipientAddress ,
159- connection . chainId
160- ) ;
161- streamId = result . streamId ;
162- txHash = result . txHash ;
163- } else {
164- const startTime = Math . floor ( Date . now ( ) / 1000 ) ;
165- const stopTime = startTime + 30 * 24 * 60 * 60 ; // 30 days from now
166- streamId = await walletServiceManager . createSablierStream (
167- selectedToken ,
168- amount ,
169- startTime ,
170- stopTime ,
171- recipientAddress ,
172- connection . chainId
163+ const selectedTokenInfo = availableTokens . find ( ( token ) => token . symbol === selectedToken ) ;
164+ const tokenForExecution =
165+ selectedProtocol === 'sablier' ? selectedTokenInfo ?. address ?? selectedToken : selectedToken ;
166+
167+ const startTime = Math . floor ( Date . now ( ) / 1000 ) ;
168+ const stopTime = startTime + 30 * 24 * 60 * 60 ;
169+
170+ const result = await executeOrQueueTransaction ( {
171+ protocol : selectedProtocol ,
172+ token : tokenForExecution ,
173+ amount ,
174+ recipientAddress ,
175+ chainId : connection . chainId ,
176+ startTime,
177+ stopTime,
178+ } ) ;
179+
180+ if ( result . queued ) {
181+ Alert . alert (
182+ 'Queued' ,
183+ 'You are offline or the network is unstable. Your transaction is queued and will run automatically when back online.' ,
184+ [ { text : 'OK' , onPress : ( ) => navigation . goBack ( ) } ]
173185 ) ;
186+ return ;
174187 }
175188
189+ const streamId = result . streamId ?? 'unknown' ;
190+ const txHash = result . txHash ;
191+
176192 const successBody =
177193 selectedProtocol === 'superfluid' && txHash
178194 ? `Stream created on-chain.\n\nTx hash:\n${ txHash } \n\nStream ID (subgraph):\n${ streamId } \n\nQuery the Superfluid subgraph using sender, receiver, and super token.`
@@ -216,6 +232,26 @@ const CryptoPaymentScreen: React.FC = () => {
216232 </ Text >
217233 </ View >
218234
235+ { ! isOnline && (
236+ < Card variant = "elevated" padding = "large" >
237+ < Text style = { styles . offlineTitle } > Offline mode enabled</ Text >
238+ < Text style = { styles . offlineText } >
239+ Transactions are queued locally and sent automatically when your connection returns.
240+ </ Text >
241+ </ Card >
242+ ) }
243+
244+ { pendingCount > 0 && (
245+ < Card variant = "elevated" padding = "large" >
246+ < Text style = { styles . pendingTitle } > Pending transactions: { pendingCount } </ Text >
247+ < Text style = { styles . pendingText } >
248+ { isQueueProcessing
249+ ? 'Processing queued transactions now.'
250+ : 'Waiting for connectivity to process queued transactions.' }
251+ </ Text >
252+ </ Card >
253+ ) }
254+
219255 { /* Token Selection */ }
220256 < Card variant = "elevated" padding = "large" >
221257 < Text style = { styles . sectionTitle } > Select Payment Token</ Text >
@@ -324,7 +360,13 @@ const CryptoPaymentScreen: React.FC = () => {
324360 { /* Create Stream Button */ }
325361 < View style = { styles . footer } >
326362 < Button
327- title = { isLoading ? 'Creating Stream...' : 'Create Payment Stream' }
363+ title = {
364+ isLoading
365+ ? 'Creating Stream...'
366+ : isOnline
367+ ? 'Create Payment Stream'
368+ : 'Queue Payment Stream'
369+ }
328370 onPress = { handleCreateStream }
329371 loading = { isLoading }
330372 variant = "crypto"
@@ -362,6 +404,24 @@ const styles = StyleSheet.create({
362404 ...typography . body ,
363405 color : colors . textSecondary ,
364406 } ,
407+ offlineTitle : {
408+ ...typography . h3 ,
409+ color : colors . text ,
410+ marginBottom : spacing . xs ,
411+ } ,
412+ offlineText : {
413+ ...typography . body ,
414+ color : colors . textSecondary ,
415+ } ,
416+ pendingTitle : {
417+ ...typography . h3 ,
418+ color : colors . text ,
419+ marginBottom : spacing . xs ,
420+ } ,
421+ pendingText : {
422+ ...typography . body ,
423+ color : colors . textSecondary ,
424+ } ,
365425 sectionTitle : {
366426 ...typography . h3 ,
367427 color : colors . text ,
0 commit comments