As discussed offline, putting the cache in chronik-client is a better choice. In addition, the initial solution of this diff has some flaws, and the new architecture should not continue here, So let's abandon it.
- Queries
- All Stories
- Search
- Advanced Search
- Transactions
- Transaction Logs
Advanced Search
Aug 7 2025
Aug 5 2025
In D18450#420593, @johnkuney wrote:
In D18437#420437, @alitayin wrote:In D18437#420414, @Fabien wrote:So let me sum up to check I understand: you have persistent storage on front-end and both memory and persistent on backend. So the persistent storage on backend is only useful if the chronik instance is a remote to save the network io?
You're right, I was explaining the original design approach above. It does have some issues, which is why it hasn't been integrated yet.
The original solution didn't have decoupling problems, but it was more oriented towards:
How to fetch all data in one go
How to cache this data, then write a complex mechanism to ensure data consistency between levelDB and chronik
The cache is only considered "complete" and usable after all transactions for an address or token are fully retrieved
Designed specifically for a few tokens/addresses with large transaction volumes
Assumed most users are chronik API users who wouldn't deploy chronik themselves
Assumed that when a user accesses address A, all records for address A would be asynchronously fetched to form a robust, complete dataset, which inherently consumes extra resources and only generates "benefits" when address A is requested frequently
These design tendencies made it a "prewarming" tool with limited use cases.So the new approach is:
Everything is processed in memory with no DB. Browser-side data storage uses localStorage
For small amounts of data, there's no need for persistence
For large amounts of data, users should deploy chronik rather than creating duplicate mirrors through persistence
No extra or duplicate data requests, zero redundancy, fetch on-demand, lightweight state, maintaining transparent proxy behavior - for users, it's simply a faster chronik client.
The original design is indeed very useful for "specific scenarios", and I might rename that original design, but chronik-cache needs to switch to the new approach.I will design a new solution and then present it to you offline.
Aug 3 2025
In D18437#420414, @Fabien wrote:So let me sum up to check I understand: you have persistent storage on front-end and both memory and persistent on backend. So the persistent storage on backend is only useful if the chronik instance is a remote to save the network io?
In D18437#420414, @Fabien wrote:So let me sum up to check I understand: you have persistent storage on front-end and both memory and persistent on backend. So the persistent storage on backend is only useful if the chronik instance is a remote to save the network io?
In D18437#420414, @Fabien wrote:So let me sum up to check I understand: you have persistent storage on front-end and both memory and persistent on backend. So the persistent storage on backend is only useful if the chronik instance is a remote to save the network io?
Aug 1 2025
In D18437#420348, @Fabien wrote:In D18437#420340, @alitayin wrote:In D18437#420336, @Fabien wrote:In D18437#420334, @alitayin wrote:In D18437#420303, @Fabien wrote:The title has a funny typo.
What is the purpose of the persistent cache ? How is it different from the base chronik storage ?
There will be a pure in-memory mode. However, between fully storage like chronik and pure in-memory, there should also be an "on-demand persistence" option. Both in the browser and in Node.js environments, this kind of flexible persistence is often needed.
"Because it's often needed" doesn't answer the question though. Why is it often needed ?
Many use cases require repeated access to specific data. For example, the address used by paybutton, or the token used by agora. Storing all of these in memory is not a good option. Selective persistence can better complement memory usage.
Storing all of these in memory is not a good option
Why ? Isn't it exactly the point of a cache ?
The goal of a cache is to avoid a costly IO operation by replacing it with a less expensive one, typically store in memory to avoid a disk lookup which is orders of magnitude slower. Another example, browser cache is about replacing networking IO with a local disk lookup.
What is your persistent cache doing ? What is the rationale behind it ?
In D18437#420336, @Fabien wrote:In D18437#420334, @alitayin wrote:In D18437#420303, @Fabien wrote:The title has a funny typo.
What is the purpose of the persistent cache ? How is it different from the base chronik storage ?
There will be a pure in-memory mode. However, between fully storage like chronik and pure in-memory, there should also be an "on-demand persistence" option. Both in the browser and in Node.js environments, this kind of flexible persistence is often needed.
"Because it's often needed" doesn't answer the question though. Why is it often needed ?
In D18437#420303, @Fabien wrote:The title has a funny typo.
What is the purpose of the persistent cache ? How is it different from the base chronik storage ?
Jul 31 2025
There are many areas for improvement. For example, comments and the Chinese I added. :-)
Jul 30 2025
Not a very confident suggestion, not sure if we can create a helper function for let params = ChronikIndexerParams here? It seems like it could reduce a bit of code, but it doesn't make much difference.
Jul 25 2025
The mock types are clearer now
Jul 13 2025
Will failover include reconnecting, switching endpoints when onclose timeout and resubscriptions?
cron only checks empty blocks. Perhaps a completion mechanism for "newly added parsed data" can be added, which would make it easier to add new parsed data in the future. Neon responds very quickly when selecting data ranges in sqp, which is better than a self-hosted database. As for the frontend, an auto-resize function or button can be added to the sidebar, as well as adapting it for mobile devices (with smaller font sizes).
Jun 2 2025
May 26 2025
May 23 2025
Cool use case, this way ALP can also carry a shorter message like sending xec, we can emphasize this point in the etoken creation instructions. Not related to this diff.
May 15 2025
I love it, Next.js and Tailwind is my favorite combination. Especially the latest version of Tailwind. If there are any design and dev needs, please ping me.
Keep the previous diff, do not pass the type.
May 14 2025
Pass in the type. Here, unlike elsewhere where used text, I used number by default here. This component is
currently only used in these two places.
May 13 2025
May 12 2025
It is better to remove the color bars on the left side of these small cards, as they may mislead people into thinking they are dismissible notifications, alerts, or clickable items.
May 6 2025
May 5 2025
I tried shortening the timeout to 500ms and performed some tests. I found that the selection strategy doesn't slow down the user's startup experience; instead, it might make it faster. The user's actual complete loading occurs when the "loading" state disappears, which is loadCashtabState in useWallet.ts. Through adding a timer for simple testing, taking my Hong Kong IP as an example, useWallet.ts:969 shows Cashtab startup duration: 2583ms. This is the time actually perceived by users. However, when using the "selection strategy" and changing the timeout from 1000ms to 500ms, the test result is 620ms for Cashtab startup duration. Therefore, finding a faster node within 500ms and establishing a connection is often faster than choosing a default one. Furthermore, this 500ms could potentially be adjusted to 400ms or 300ms, meaning "if we can't find a faster node within 300-400ms, it doesn't matter anymore." WebSocket connection establishment speed is 2-3 times that of ping, and it's easy to prove through testing that lower WebSocket latency means lower query latency.
May 4 2025
My view is that this approach is worthwhile.
May 2 2025
May 1 2025
Apr 28 2025
rebuild again :-) please
Add test for manual close
@bot preview-cashtab
Apr 26 2025
Add README.md and npm version patch
Removed the previous delay handling. Only ensure in this diff that faulty nodes can be switched correctly.
Apr 24 2025
Based on offline discussions,
Joey's view is correct. "A node that can establish a WebSocket connection (_websocketUrlConnects) but immediately throws onerror or onclose after connection" was inferred from a March failure,
“A node that can establish a WebSocket connection (_websocketUrlConnects) but immediately throws onerror or onclose after connecting,” is not an accurate description; it’s more of an extreme example.
Apr 23 2025
Apr 22 2025
This diff will only address the issue of _websocketUrlConnects not closing the WebSocket under timeout conditions.
Apr 18 2025
keep the first modification to close WS
Apr 17 2025
Extra comments and trailing whitespace removed
update README.md
update README.md and npm version minor
Apr 16 2025
Better test url orders
Some minor adjustments regarding the above.
add package-json
rebase and add test
Apr 15 2025
add test, in the test, i don't mock measureWebsocketLatency, but instead use asynchronous actual testing to
keep it simple.
Keep using Infinity, adjust the output to display in ms
Directly return -1 in measureWebsocketLatency for timeout cases
Based on what was mentioned earlier, I first moved appendWsUrls out of the class in D17935 and reused it here.
Additionally, I removed the concurrent and batch settings, and optimized and streamlined the Sort function (the
original sort function considered multiple rounds of testing, making the code more complicated)
Apr 12 2025
Apr 10 2025
// Using the static method with strategy
const chronik = await ChronikClient.useStrategy(
ConnectionStrategy.ClosestFirst, urls, maxConcurrentTests // optional parameter, default is 20
);
Node selection is implemented using static methods in chronikclient while maintaining consistency with existing methods. Removed the original npm list
test. Moved measureWebsocketLatency and sortNodesByLatency to chronikclient.ts
After this modification, it no longer dynamically selects the best node. Instead, it rearranges the
node order only once during initialization. Removed the URL string and kept only the array to maintain consistency with chronikclient.
And use as-order as default
After this modification, it no longer dynamically selects the best node. Instead, it rearranges the node order only once during
initialization. Removed the URL string and kept only the array to maintain consistency with chronikclient.
Apr 9 2025
I have tested the modified chronik-client locally and it switches smoothly. Perhaps I could deploy it on an actual test domain for public testing?
