A customizable, zero-dependency clock for your Bitcoin Core node.
<script
type="module"
src="https://unpkg.com/block-clock/dist/index.js"
></script>
For extra security, add sub-resource integrity by calculating the sha384 of the js file:
cat block-clock-index.js | openssl dgst -sha384 -binary | openssl base64 -A
Then use it in the script property:
<script
type="module"
src="https://unpkg.com/block-clock/dist/index.js"
integrity="sha384-YOURCOMPUTEDSHA384"
></script>
npm install block-clock
<block-clock
rpcUser="<YOUR_RPC_USER>"
rpcPassword="<YOUR_RPC_PASSWORD>"
rpcEndpoint="<YOUR_RPC_ENDPOINT>"
darkMode
>
</block-clock>
Watch our meeting with Bitcoin Design Community for an explanation:
block-clock
is a working web component implementation of the Block Clock designed by the Bitcoin Design Community for the work-in-progress Bitcoin Core App design. The goal of that project is to provide a more intuitive and visually appealing frontend for Bitcoin Core nodes, and block-clock
is a part of that effort.
The block-clock
works by consuming a set of Bitcoin Core RPC credentials at an endpoint and a set of (optional) props. It can also accept a callback for Bitcoin Core nodes behind a proxy, so long as the response data returned by the proxy matches response returned by Bitcoin Core. Using these, it fetches block data and calculates the time between block confirmations to create a visual display of when each block was mined.
The visualization begins at blocks that were mined within the last 12 hour period. It shows the blocks mined starting from either 12 A.M. or 12 P.M. to the current local time. Therefore, the "fill" of the clock always represents the current local time down to the second. Note: There is also a 1-hour interval mode which can be turned on by setting oneHourIntervals
on the block-clock
component. This is useful if you want to see the past hour's block times. It is also highly recommended to use when connecting Mutinynet nodes. Mutinynet is a fork of Bitcoin Core which uses 30-second block times to make developing applications easier. Because block times are so short, the clock may not function properly if using the default 12-hour intervals.
By default, unconfirmed blocks are shown in gray and confirmed blocks are shown in shades from red to yellow. The first 6 most recently confirmed blocks having a tint of red, with the most recently confirmed block being completely red, and the next 5 blocks being progressively more yellow, after which the color remains consistent. These colors are fully configurable.
As block data is loaded, it is saved in localStorage in the browser, so that subsequent visits to the page or refreshes won't require data to be reloaded. Only blocks that have been mined since the last block saved to localStorage
will need to be loaded.
block-clock
uses XState to create state machines that make it easy to model how events change the state of the clock. This has the benefit of making the state changes in the clock easier to reason about, as well as import into other projects.
See the state machine here.
Voltage is a quick way to get a Bitcoin Core node up and running, and the block-clock
is also integrated on our site. See our docs for more info on creating a Bitcoin Core node.
block-clock
can be used anywhere web components can be used. When working with purely client-side frameworks like React, you may import and use it directly, like so:
import "block-clock";
function App() {
return (
<div className="App">
...
<div style={{ width: 200, height: 200 }}>
<block-clock
rpcUser="<YOUR_RPC_USER>"
rpcPassword="<YOUR_RPC_PASSWORD>"
rpcEndpoint="<YOUR_RPC_ENDPOINT>"
darkMode
></block-clock>
</div>
...
</div>
);
}
export default App;
In SSR frameworks like Sveltekit or NextJS, be sure to wait for the DOM to load first before importing:
<script lang="ts">
import { onMount } from 'svelte';
onMount(() => {
import('block-clock');
});
</script>
<div style="display: flex; justify-content: center; align-items: center; height: 100vh">
<div style="width: 200px; height: 200px;">
<block-clock
rpcUser="<YOUR_RPC_USER>"
rpcPassword="<YOUR_RPC_PASSWORD>"
rpcEndpoint="<YOUR_RPC_ENDPOINT>"
darkMode
>
</block-clock>
</div>
</div>
By default, Bitcoin Core RPC doesn't handle CORS headers so if you try to connect the blockclock from your browser to a locally running Bitcoin Core instance it will fail. You can solve this putting the RPC endpoint behind a proxy, for example:
npx local-cors-proxy --proxyUrl http://localhost:8332
Where 8332
is the port of the bitcoin core RPC REST server.
Then use the proxy url provided in your node's rpcEndpoint
.
As an example, here is some code you can use to run a pruned node locally to test the block clock:
~/your/path/to/bitcoin-core/bin/bitcoind \
-rpcuser=admin \
-rpcpassword=admin \
-rpcport=8332 \
-assumevalid=00000000000000000000b863b337fc0fa521dc17b25d1b7b22c78e0609316a6d \
-prune=600
This sets admin
as the rpc user and password.
If you need instructions on how to install bitcoin core checkout this video (Mac) or look for a tutorial for your specific operating system.
Attribute | Type | Description | Default | Example |
---|---|---|---|---|
rpcUser |
string |
The RPC User. Required. | "" | <MY-USERNAME> |
rpcPassword |
string |
The RPC password for the user. Required. | "" | <MY-PASSWORD> |
darkMode |
boolean |
Whether the block-clock is being shown on a light or dark background. Optional. |
false |
false |
devMode |
boolean |
Whether to display variables for debugging. Optional. | false |
false |
oneHourIntervals |
boolean |
Whether the clock should reset every hour. Used for Mutinynet nodes due to short block times. Optional. | false (i.e. 12 hour intervals). |
false |
isStopped |
boolean |
Toggle whether the Bitcoin Node is stopped and show the stopped state. Used when the node is offline or RPC is unreachable. Optional | false |
false |
theme |
BlockClockTheme |
The color theme(s) for the blocks. The first color in the array represents the unconfirmed transactions. The index of the item between the first and the last items in the array represent the color of that block's confirmations + 1 (i.e., the color at i = 2 is the color of the block with 1 confirmation, i = 3 is the color of the block with 2 confirmations, etc.). The last color in the array represents the color of all remaining blocks. Optional. | See DEFAULT_THEME . |
See DEFAULT_THEME . |
To see the storybook and play around with the various attributes:
yarn storybook
If you find a problem, please open an issue. PRs welcome!
npm run build
npm run publish
MIT