-
Notifications
You must be signed in to change notification settings - Fork 16
Feat connect chronik websocket directly #522
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
c1f0983 to
049cf5a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR removes the dependency on paybutton-server websocket and integrates direct connection to the Chronik websocket for receiving payment notifications. This change eliminates the need for an intermediary server and allows the application to receive transaction data directly from the blockchain indexer.
- Adds Chronik client integration with websocket support for real-time transaction monitoring
- Implements OP_RETURN data parsing functionality for payment metadata
- Updates Widget and PayButton components to use the new Chronik websocket instead of the legacy socket.io connection
Reviewed Changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| react/package.json | Adds chronik-client-cashtokens, decimal.js, and ecashaddrjs dependencies |
| react/lib/util/types.ts | Extends Transaction interface with opReturn field |
| react/lib/util/socket.ts | Adds Chronik websocket setup and message handling functions |
| react/lib/util/opReturn.ts | Implements OP_RETURN data parsing utilities |
| react/lib/util/chronik.ts | New file with complete Chronik client integration and transaction processing |
| react/lib/components/Widget/WidgetContainer.tsx | Updates to handle internal transaction state management |
| react/lib/components/Widget/Widget.tsx | Replaces socket.io setup with Chronik websocket |
| react/lib/components/PayButton/PayButton.tsx | Replaces socket.io setup with Chronik websocket |
| address, | ||
| timestamp: transaction.block !== undefined ? transaction.block.timestamp : transaction.timeFirstSeen, | ||
| confirmed: transaction.block !== undefined, | ||
| opReturn, |
Copilot
AI
Jul 23, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The rawMessage field is being set from parsedOpReturn but this conflicts with line 155 where opReturn already contains the stringified JSON with rawMessage. This creates inconsistent data where the top-level opReturn contains serialized data but individual fields contain parsed values.
| opReturn, | |
| opReturn: JSON.stringify(parsedOpReturn), // Ensure opReturn matches parsedOpReturn |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
very confusing message, referencing the wrong line, and bad suggestion overall, since the main purpose of sending the opReturn is to have access to it without any processing.
react/lib/util/socket.ts
Outdated
| params.setTxsSocket(undefined); | ||
| } | ||
|
|
||
| const newChronikSocket = await initializeChronikWebsocket(params.address, (transactions: Transaction[]) => { onMessage(transactions, params.setNewTxs, params.setDialogOpen, params.checkSuccessInfo) }); |
Copilot
AI
Jul 23, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] This line exceeds reasonable length and has complex nested function calls. Consider extracting the callback function to improve readability: const handleTransactions = (transactions: Transaction[]) => onMessage(transactions, params.setNewTxs, params.setDialogOpen, params.checkSuccessInfo);
| const newChronikSocket = await initializeChronikWebsocket(params.address, (transactions: Transaction[]) => { onMessage(transactions, params.setNewTxs, params.setDialogOpen, params.checkSuccessInfo) }); | |
| const newChronikSocket = await initializeChronikWebsocket(params.address, handleTransactions(params.setNewTxs, params.setDialogOpen, params.checkSuccessInfo)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just break some lines
| // if (thisTxsSocket !== undefined) { | ||
| //thisTxsSocket.disconnect(); | ||
| //setThisTxsSocket(undefined); | ||
| // } |
Copilot
AI
Jul 23, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Commented-out cleanup code should be removed or properly implemented. The cleanup logic for Chronik websockets may be needed to prevent memory leaks.
| // if (thisTxsSocket !== undefined) { | |
| //thisTxsSocket.disconnect(); | |
| //setThisTxsSocket(undefined); | |
| // } | |
| if (thisTxsSocket !== undefined) { | |
| thisTxsSocket.disconnect(); | |
| setThisTxsSocket(undefined); | |
| } |
| // if (txsSocket !== undefined) { | ||
| // txsSocket.disconnect(); | ||
| //setTxsSocket(undefined); | ||
| // } |
Copilot
AI
Jul 23, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Commented-out cleanup code should be removed or properly implemented. The cleanup logic for Chronik websockets may be needed to prevent memory leaks.
| // if (txsSocket !== undefined) { | |
| // txsSocket.disconnect(); | |
| //setTxsSocket(undefined); | |
| // } | |
| if (txsSocket !== undefined) { | |
| txsSocket.disconnect(); | |
| setTxsSocket(undefined); | |
| } |
| txsSocket.disconnect(); | ||
| setTxsSocket(undefined); | ||
| } | ||
| // if (txsSocket !== undefined) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you feel these might be necessary and don’t want to delete it completely, it would be good to leave a comment explaining your hesitation.
react/lib/util/chronik.ts
Outdated
| address: string, | ||
| onTransaction: Function | ||
| ): Promise<WsEndpoint> => { | ||
| const chronik = new ChronikClient(['https://chronik.e.cash']); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be in paybutton-config.json, not hardcoded.
react/lib/util/socket.ts
Outdated
| params.setTxsSocket(undefined); | ||
| } | ||
|
|
||
| const newChronikSocket = await initializeChronikWebsocket(params.address, (transactions: Transaction[]) => { onMessage(transactions, params.setNewTxs, params.setDialogOpen, params.checkSuccessInfo) }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just break some lines
Klakurka
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ed59d82 to
4760cc2
Compare
Klakurka
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Klakurka
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Try opening
localhost:10001, opening the network tab, clearing the logs, clicking the 'Basic' paybutton to open the dialog. On the first opening, you'll see 3 web sockets open. Close the dialog and clear the network logs again. Open it again and you'll see no new web socket. Why 3 on the first 1? Why 0 on the 2nd one? - Build warnings:
react/lib/example-config.json
Outdated
| "https://xec.paybutton.io", | ||
| "https://chronik1.alitayin.com", | ||
| "https://chronik2.alitayin.com", | ||
| "https://chronik.e.cash", | ||
| "https://chronik-native1.fabien.cash", | ||
| "https://chronik-native2.fabien.cash", | ||
| "https://chronik-native3.fabien.cash", | ||
| "https://chronik.pay2stay.com/xec", | ||
| "https://chronik.pay2stay.com/xec2" | ||
| ], | ||
| "bitcoincash": ["https://bch.paybutton.io", "https://chronik.pay2stay.com/bch"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's use the .org URLs instead of the .io ones as access will eventually be restricted at some point in the future to only our server(s).
are you testing on the demo page? we open a new websocket instance for each widget might be the reason it is opening more than one. And we stick with the first connection open for a dialog, that is why it does not open again |
|
Yes - demo page. AFAICT it is sending non-ws messages that trigger payment detection / onSuccess. Can you check that? |
8fa8252 to
ae27962
Compare
|
My main concern with this is that we're introducing the possibility of a user seeing onSuccess run but there still potentially be an issue if there is some kind of problem on the server preventing payment triggers from firing (eg. wp plugin. |
0b5b11b to
0859baa
Compare
|
Couple of things:
|
0859baa to
68a86bd
Compare
chedieck
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just requesting the fix of a typo in a variable name.
Most of the code here is copy + pasted from paybutton-server, which is fine for now, but if we want to edit this code in the future we probably should consider actually separating it in a 3rd repo that we could import on both paybutton-server and paybutton, to avoid having to edit in both repos and risking have conflicting behavior between them.
react/lib/util/chronik.ts
Outdated
| address: string, | ||
| setNewTx: Function | ||
| ): Promise<WsEndpoint> => { | ||
| const networSlug = getAddressPrefix(address) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo here, should be networkSlug






Related to #519
Depends on
Description
Removed connection with paybutton-server websocket and added connection to chronik websocket directly.
Test plan