Skip to content

Comments

Add Stratum V2 (SV2) protocol support#1553

Draft
warioishere wants to merge 3 commits intobitaxeorg:masterfrom
warioishere:feature/stratum-v2-support
Draft

Add Stratum V2 (SV2) protocol support#1553
warioishere wants to merge 3 commits intobitaxeorg:masterfrom
warioishere:feature/stratum-v2-support

Conversation

@warioishere
Copy link

@warioishere warioishere commented Feb 14, 2026

Summary

Adds Stratum V2 binary protocol support alongside the existing V1 JSON-RPC implementation. Tested on a BM1370 bitaxe against a local SRI server and the SRI reference pool — full 1.3 TH/s hashrate with shares accepted.

What's included:

  • SV2 binary protocol: frame encoding/decoding, mining channel messages (SetupConnection, OpenStandardMiningChannel, NewMiningJob, SetNewPrevHash, SetTarget, SubmitSharesStandard)
  • SV2 Noise encryption: Noise_NX handshake with ChaCha20-Poly1305 transport via libsecp256k1 (git submodule v0.6.0)
  • Protocol coordinator with separate V1/V2 task files and fallback/recovery logic
  • Protocol selectable via NVS config and AxeOS Pool Settings UI (both primary and fallback pool)

What works:

  • Full hashrate (1.3 TH/s on BM1370)
  • Encrypted connection via Noise protocol
  • Share submission and acceptance
  • Pool difficulty tracking via SetTarget
  • V1/V2 protocol switching and fallback

Open decisions

Based on review feedback, the following items are being discussed before this PR is finalized:

1. ntime rolling removal — The current implementation rolls ntime to generate unique ASIC work. This is unnecessary since BM1366/BM1368/BM1370 all do hardware version rolling, which provides sufficient search space. ntime should track real time, not be used as a work diversifier. Will be removed.

2. Standard vs Extended Channels — Currently only standard channels are implemented. The BM1397 (Bitaxe Max) doesn't support hardware version rolling, so standard channels alone won't work for it. Options under discussion:

  • Standard channels only (BM1397 excluded from SV2 until extended channels are added)
  • Extended channels only (all ASICs supported, reuses SV1 coinbase/merkle logic, also enables coinbase_decoder hookup)
  • Both, with runtime ASIC-based channel type selection

Test plan

  • SV2 connection + Noise handshake against SRI server
  • Full hashrate (1.3 TH/s) with BM1370
  • Shares accepted, no duplicates
  • Dashboard loads in SV2 mode
  • V1 mode unaffected
  • Tested against SRI reference pool
  • Test on other ASIC variants (BM1366, BM1368, BM1397)

Test servers

Public SV2 test server:

  • Host: blitzpool-test.yourdevice.ch
  • Port: 3333
  • Authority Public Key: 9bCoFxTszKCuffyywH5uS5o6WcU4vsjTH2axxc7wE86y2HhvULU
  • running on regtest

SRI reference pool (confirmed working):

  • Host: 75.119.150.111
  • Port: 3333
  • Authority Public Key: 9auqWEzQDVyd2oe1JVGFLMLHZtCo2FFqZwtKA5gd9xbuEu7PH72

For transparency: most of this implementation was done with the help of Claude (Opus 4.6). I hope that doesn't detract from the goal of bringing SV2 support to bitaxe.

@warioishere warioishere force-pushed the feature/stratum-v2-support branch from 8882a06 to 9551b7e Compare February 15, 2026 07:58
@mutatrum
Copy link
Collaborator

Please add some screenshots.

I've had a cursory look at the code, will do a more in-depth review later. I'm not opposed to agentic development, however, only if the author is familiar with the codebase and does first line code reviews as well. This codebase looks decent, but I did see some areas where it could benefit more from separation of concerns.

For example: would it be cleaner to have a dedicated stratum_v2_task.c, instead of intermingling the two protocols in stratum_task.c? This holds for all touch-points of sv2, try to make it as clean as possible, with the least amount of if sv else sv2 statements sprinkled throughout the code.

If you have Claude work on it, please make it aware of #901, and have it keep that in mind that if we're splitting off work production protocols, this is something that I might like to add as well in the future.

@warioishere
Copy link
Author

warioishere commented Feb 15, 2026

Please add some screenshots.

I've had a cursory look at the code, will do a more in-depth review later. I'm not opposed to agentic development, however, only if the author is familiar with the codebase and does first line code reviews as well. This codebase looks decent, but I did see some areas where it could benefit more from separation of concerns.

For example: would it be cleaner to have a dedicated stratum_v2_task.c, instead of intermingling the two protocols in stratum_task.c? This holds for all touch-points of sv2, try to make it as clean as possible, with the least amount of if sv else sv2 statements sprinkled throughout the code.

If you have Claude work on it, please make it aware of #901, and have it keep that in mind that if we're splitting off work production protocols, this is something that I might like to add as well in the future.

Hey, I'll refactor this using a protocol coordinator pattern. I'll extract V1 into its own task (stratum_v1_task), remove the cross-protocol dependencies from sv2_task,
and add some helper functions for the shared operations like share submission. The coordinator will handle all the fallback/recovery logic instead of having tasks create each other.

I'm keeping create_jobs_task unified since it already works fine, and I don't think the global_state union or vtable stuff is worth the complexity. I'll remove the old stratum_task.c once everything tests out.

I read #901 already, but I thought about usings sv2 capability to connect to a separate jd-client that can connect to bitcoin core via Sjors TP, that would give us also full control over templates and dezentralize things further, but yea, I can have a look onto this option directly getting templates from core as its far simplier then using a jd-client.

We can look at this in further developement, okay?

@mutatrum
Copy link
Collaborator

mutatrum commented Feb 15, 2026

GetBlockTemplate mining is definitely for another PR, this is already quite big.

Some more code review remarks:

  • sv2_api.h filename mismatches sv2_protocol.c;
  • How much effort is it to support NewExtendedMiningJob so coinbase_decoder can be hooked up?
  • Not sure if the way the config works makes sense now:
    image The connection security radiobox is mutually exclusive with the protocol options, as is the sv2 Pool Fingerprint. It would make more sense to first have the Protocol option, and make the sv1/sv2 options only visible for the selected protocol. E.g. only show Connection Security on SV1, only show Pool Fingerprint on SV2;
  • Primary and secondary pool should both have the sv2 option. Not sure how the liveliness check on the primary pool should work with sv2?
  • Make naming a bit more consistent: sv2_task is unclear, which task is it? The current naming is not perfect either, but at least it shouldn't be made more confusing :-)

On libsecp256k1:

  • With the submodule, does the project checkout change now? And how does this transition for people already having checked out the project?
  • How is the version of the dependency managed?
  • Both questions might need stuff in the readme added.

@warioishere
Copy link
Author

warioishere commented Feb 16, 2026

New clones need git clone --recursive, and existing checkouts need a one-time git submodule update --init --recursive after pulling, otherwise the build fails on an empty directory.

The submodule is pinned to commit 0cdc758 (tagged v0.6.0 of bitcoin-core/secp256k1). Git tracks the exact commit hash, so everyone gets the same version. Updating means checking out a new tag in the submodule dir and committing the pointer change. I will add this to the README.

I'd love to see extended channel support as well, but I think it makes sense to handle it in a separate PR. For now, let's prioritize standard channels here.

Standard channels have a clear advantage for a device like the BitAxe: the network overhead is minimal since the pool precomputes everything and the miner only receives the block header. Extended channels would require handling the full coinbase transaction on the miner side, which adds complexity here now to review and test.

Once standard channels are solid, we can build on that foundation and add extended channel support with coinbase TX handling in a follow-up PR.

Will keep the sv2_api.h filename mismatches sv2_protocol.c in mind during refactoring now and also consider a better naming.

Currently, we only have options based on what Protocol we choose so users dont get confused:

grafik

and for Sv2

grafik

I have also added Sv2 Mode for Fallback Pool.

grafik

Would you like to have everything in a single commit after refactoring? Should be done by this evening.

@warioishere warioishere force-pushed the feature/stratum-v2-support branch from 9551b7e to 0470129 Compare February 16, 2026 16:35
@warioishere
Copy link
Author

Refactoring is done, everything squashed into a single commit.

Here's what changed since last time: V1 and V2 now live in their own task files (stratum_v1_task.c and stratum_v2_task.c), with a protocol coordinator handling all the fallback and recovery logic. The old stratum_task.c is gone. Fixed the sv2_api.h naming mismatch, it's consistently sv2_protocol now.

Both primary and fallback pool support SV2 selection, and the UI only shows relevant options per protocol. Heartbeat probing works for both V1 and V2 primaries, so liveness checks are covered regardless of protocol combo.

Also fixed a bunch of stability issues with protocol switching - the old implementation would crash or restart the device when switching between V1 and V2 at runtime. That's sorted now.

Extended channel support and GetBlockTemplate mining are left for follow-up PRs as discussed.

Ready for review 🚀

@mutatrum
Copy link
Collaborator

No need to do squash and force-push. This makes it harder to review incremental changes.

@warioishere
Copy link
Author

i made a backup of the branch before squashing, should I revert?

@mutatrum
Copy link
Collaborator

i made a backup of the branch before squashing, should I revert?

No it's fine for this PR. Sometime a squash and/or force push is necessary to fix merges, so no problem. Just for future reference, the code will be squashed into a single commit on merge anyways.

@mutatrum
Copy link
Collaborator

Can you see if you can update your branch, it looks like some changes that were added to master have been added here as well. These might drop out if you update.

@warioishere warioishere force-pushed the feature/stratum-v2-support branch from 0470129 to b3d3a46 Compare February 16, 2026 18:37
@warioishere
Copy link
Author

Can you see if you can update your branch, it looks like some changes that were added to master have been added here as well. These might drop out if you update.

Updated the branch, rebased onto latest master. The 3 duplicate commits dropped out. Should be a cleaner diff now.

Add full Stratum V2 mining protocol support to the bitaxe, enabling
encrypted communication with SV2 pools via Noise_NX handshake
(secp256k1+EllSwift, ChaChaPoly, SHA256). Includes a robust
protocol coordinator for clean failover between any combination
of V1/V2 primary and fallback pools without device restarts.

Protocol implementation:
- SV2 binary protocol (components/stratum_v2/): SetupConnection,
  OpenStandardMiningChannel, NewMiningJob, SetNewPrevHash, SetTarget,
  SubmitShares with proper frame encoding/decoding
- Noise encryption (sv2_noise.c): Full NX handshake with optional
  authority public key verification (TOFU mode when unconfigured)
- libsecp256k1 v0.6.0 as git submodule for elliptic curve operations

Protocol coordinator and fallback:
- Non-blocking event-driven coordinator manages protocol task lifecycle
- Supports all 4 failover combinations: V2->V1, V2->V2, V1->V2, V1->V1
- Timer-based heartbeat probes primary pool during fallback operation
- User-selected fallback (dashboard toggle) disables auto-recovery
- Clean state transitions: queue clear, share stats reset, proper
  task shutdown with event synchronization

Key reliability fixes:
- Heap-allocate sv2_conn to prevent dangling pointer after task exit
- Dynamic protocol check in create_jobs_task (was cached at startup,
  causing memory corruption on protocol switch)
- Single event per task exit (was double-signaling coordinator)
- Remove esp_restart() from V1 task, notify coordinator instead
- Fix V1 transport handle leak (destroy after close)
- Remove close_connection race from asic_result_task

Frontend and configuration:
- NVS settings for SV2 authority pubkey and fallback pool protocol
- Pool settings UI: protocol selector and SV2 pubkey for both pools,
  V1-only options hidden when SV2 selected
- Display: hide block height and scriptsig in SV2 mode (not available
  in standard channel), show protocol indicator instead
- OpenAPI spec updated with new SV2 configuration fields
@warioishere warioishere force-pushed the feature/stratum-v2-support branch from b3d3a46 to 51787d9 Compare February 16, 2026 18:40
coordinator_state_t and coordinator_event_t are only used inside
protocol_coordinator.c, no need to expose them in the header.
@jbesraa
Copy link

jbesraa commented Feb 17, 2026

Which parts of SV2 protocol does this implement, is it Mining protocol or JD as well? Does it include both extended and standard channels support?
Would be nice if you could provide instructions on how to test this with my bitaxe.

@warioishere
Copy link
Author

warioishere commented Feb 17, 2026

currently no extented channels, that will be part of a next PR. and no JD-client, but I am building an easy to setup full stack deployment which you could run on a raspberry pi, or even on the node itself. Contains a JD-Client, TP from Sjor, and a bitcoincore setup build with --enable-multiprocess so that the IPC Unix socket connection method can be used:

https://github.com/warioishere/sv2-apps

@warioishere
Copy link
Author

warioishere commented Feb 17, 2026

jst confirmed the implementation works also againstthe original sv2 reference server:

authority_pubkey = "9auqWEzQDVyd2oe1JVGFLMLHZtCo2FFqZwtKA5gd9xbuEu7PH72" 
pool_address = "75.119.150.111" 
pool_port = 3333 

@mutatrum
Copy link
Collaborator

Do you have a Max (BM1397) device to test against? The others are functionally equivalent with respect to job construction/asic comms.

@plebhash
Copy link

ntime rolling for ASIC work generation

ntime rolling on a bitaxe seems quite backwards?

@plebhash
Copy link

plebhash commented Feb 17, 2026

elaborating on the comment above

IIUC the BM1370 doesn't support version rolling, which is forcing you to roll ntime so you can stick with a standard channel, right?

This is explicitly allowed by the SV2 spec.

"allowed" but not definitely not encouraged... rolling ntime can have bad consequences on consensus level

as a rule of thumb, ntime should only be increased when we want to reset the search space and we know we've been hashing for longer than 1s

and it should happen like this:

  • increment 1 unit on ntime, hash for at least 1s
  • increment 1 unit on ntime, hash for at least 1s
  • ...

or at least some variation that respects ntime as something that progresses together with real time, and not something that rolls indefinitely into the past or future (with undesired consequences)


overall, I think it's a very good idea to support Sv2 Standard Channels as a "first class citizen" on AxeOS

but for edge cases where ASICs cannot do version rolling, I would go with Extended Channels and not try to reinvent the wheel

@warioishere
Copy link
Author

warioishere commented Feb 17, 2026

IIUC the BM1370 doesn't support version rolling

Can you elaborate on this? From what I see in the codebase, the BM1370 does do hardware version rolling:

  • BM1370_set_version_mask() writes the mask to register 0xA4 on the chip, and it's called during init with 0x1fffe000
  • The ASIC result struct includes a 16-bit version field that gets shifted left 13 (version_bits = ntohs(asic_result.job.version) << 13), matching the mask exactly
  • The rolled version is reconstructed via OR: version | version_bits

These are latest-gen Antminer S21 chips — would be surprising if they dropped version rolling support. The BM1397 is the only one where set_version_mask is a no-op placeholder.

That said, you're right that the ntime rolling approach is wrong regardless. Even if the ASIC does version roll, bumping ntime by +1 every 500ms job send is not how ntime should be used. I'll fix that — either remove the offset entirely (since version rolling gives enough search space) or clamp it to real elapsed wall-clock time.

What would you suggest as the right approach here for standard channels?

@warioishere
Copy link
Author

Do you have a Max (BM1397) device to test against? The others are functionally equivalent with respect to job construction/asic comms.

the BM1397 is the only ASIC where set_version_mask is a no-op — it doesn't do hardware version rolling. That means SV2 standard channels won't give it enough search space even with jst ntime rolling, which isn't a good solution (see discussion with plebhash above).

I think there are two options here:

  1. Exclude the BM1397 from SV2 support in this PR entirely, and only enable it later when we add extended channel support
  2. Drop SV2 support for the Bitaxe Max altogether, given it's the oldest generation

What do you think makes more sense?

@mutatrum
Copy link
Collaborator

Excluding a chip from a protocol is a bit of a nasty dependency. Maybe adding Extended channels also puts it more in line with how SV1 currently works. I can't really oversee how much more work that is to support though.

@warioishere
Copy link
Author

Yeah, I agree excluding a chip entirely from a protocol isn't great. I think the clean approach is:

  • BM1397 can't do hardware version rolling, so standard channels don't give it enough search space
  • BM1366/BM1368/BM1370 all have working version rolling, so standard channels work fine

The channel type decision is just a runtime check on the ASIC ID — use OpenExtendedMiningChannel for BM1397, OpenStandardMiningChannel for the rest. That way the BM1397 gets an extranonce to vary (like SV1 today), and the others get the simpler standard channel path.

For this PR I'd scope it to standard channels only, which means BM1397 stays on SV1 for now. Extended channel support in a follow-up PR would unlock SV2 for the Max as well.

@warioishere
Copy link
Author

warioishere commented Feb 17, 2026

I looked into the effort for Extended Channel support. The good news is most of the heavy lifting already exists — calculate_coinbase_tx_hash() and calculate_merkle_root_hash() from the SV1 path do exactly what Extended Channels need (coinbase prefix + extranonce + suffix → merkle root). It's roughly ~700-800 lines of new code across 6 files, mainly new message parsers/builders in sv2_protocol.c and a generate_work_sv2_extended() that reuses the SV1 merkle computation.

One option would be to drop Standard Channels entirely and go straight to Extended Channels. That way:

  • All ASICs are supported (including BM1397/Max)
  • No ntime rolling needed — extranonce variation gives unlimited search space
  • Closer to how SV1 works today, so less conceptual difference
  • No need for channel-type branching logic

The tradeoff is that Extended Channels put more work on the miner (coinbase + merkle computation), but the ESP32 already does this for SV1 without issues.

What would you suggest — Extended-only, or keep both with a runtime ASIC check? Thats about a week more effort or so.

@plebhash
Copy link

IIUC the BM1370 doesn't support version rolling

Can you elaborate on this? From what I see in the codebase, the BM1370 does do hardware version rolling:

I'm not claiming this is true and I don't know whether BM1370 can do version rolling or not. I just got this understanding from the PR description.

The solution: Instead of rolling the version (which breaks BM1370's OR-based version reconstruction when carry transitions flip bits), we roll ntime on each work send. ntime is in the 2nd SHA-256 block (bytes 68-71), not in the midstate (bytes 0-63), so different ntime values produce unique hashes while midstates and the base version stay constant. This is explicitly allowed by the SV2 spec.

@adammwest
Copy link
Contributor

but I still think that rolling ntime is a really bad idea and I strongly advise against merging this PR with that functionality.

@plebhash
why is ntime rolling bad?
e.g , the intel chip BZM2 uses it inside the chip
source - 256foundation/mujina#28 (comment)

Its the next cheapest thing, aside from nonce in time

@plebhash
Copy link

plebhash commented Feb 20, 2026

but I still think that rolling ntime is a really bad idea and I strongly advise against merging this PR with that functionality.

@plebhash why is ntime rolling bad? e.g , the intel chip BZM2 uses it inside the chip source - 256foundation/mujina#28 (comment)

if you know what you're doing yeah it's possible, I woudn't be suprised if there were other industry examples aside from BZM2

but rolling ntime has plenty of consensus-related footguns while rolling in both directions, so I don't think it's a good idea to embed it as a first-class citizen feature on a FOSS project, mainly due to the unnecessary/avoidable added complexity and maintenance burden, especially given there's viable alternatives

Its the next cheapest thing, aside from nonce in time

assuming version rolling is available, isn't that equally cheap?


anyways, since you mentioned 256foundation/mujina#28 (comment) I'll tag @johnny9 to get his own take on this

@johnny9
Copy link
Collaborator

johnny9 commented Feb 20, 2026

ntime rolling is not bad and will be increasingly necessary as its clear to me that future chips will be doing it as well. every bit adds an exponential amount of nonce space. We're talking about a few seconds difference in the timestamp. This is not a problem for consensus.

It can be configured of course but in the BZM2's case it will be needed to give the mcu room to process as it will need the additional space to hit the hard real time demands of the work generation.

I would try to avoid rolling ntime on the mcu itself and only let the chips do it when necessary. We should have support for whatever sv2 needs to let us roll ntime.

@plebhash
Copy link

plebhash commented Feb 20, 2026

for whatever sv2 needs to let us roll ntime

Sv2 is mostly agnostic about that

jobs are broadcast with a min_ntime parameter and that's it

if clients break consensus by rolling too far into the future, their shares SHOULD be rejected (but this is just me saying, the spec doesn't even mention that AFAIR)

…s detection

- Add NVS config for SV2 channel type (extended/standard) per pool
- Expose sv2ChannelType and fallbackSv2ChannelType in /info endpoint
- Add channel type selector in pool settings with extended/standard radio buttons
- Disable standard channel option for BM1397 (requires extended channels)
- Add Mode label in dashboard Pool card showing active protocol
- Use hasCoinbaseVisibility() helper for conditional dashboard elements
- Fix extranonce_size interpretation: it is the miner's rollable portion, not total
- Add testnet/regtest network auto-detection from user address prefix
- Support parametric bech32 HRP (bc/tb/bcrt) and base58 version bytes
- Remove ntime rolling for SV2 standard channels (version rolling only)
- Remove info icons from SV2-related texts in pool configuration
- Add calculate_coinbase_tx_hash_bin() for binary coinbase hashing
- Add SV2 extended channel message types and parsing functions
@plebhash
Copy link

plebhash commented Feb 20, 2026

We're talking about a few seconds difference in the timestamp. This is not a problem for consensus.

ok after some reflection I guess I can entertain that, thanks for clarifying

we have 2h=7200s to roll into the future before breaking consensus

2^12=4096
2^13=8192

so if we limit ntime rolling to the 12 LSBs, we're risk-free on breaking consensus

interestingly, Sv2 spec states that Standard Jobs are limited to 280TH/s max before rolling ntime

if we lift restrictions on ntime rolling, we multiply that ceiling by 4096

so ok, I retract what I said above

@johnny9 how many ntime bits are people rolling in the industry?

@johnny9
Copy link
Collaborator

johnny9 commented Feb 21, 2026

@johnny9 how many ntime bits are people rolling in the industry?

The BZM2 does 7 bits max.

@plebhash
Copy link

@johnny9 how many ntime bits are people rolling in the industry?

The BZM2 does 7 bits max.

interesting thanks

so assuming BIP320 version rolling and 7 bits ntime rolling, Sv2 Standard Jobs have a ceiling of 280T*128=35.8PH/s

@warioishere
Copy link
Author

warioishere commented Feb 21, 2026

okay guys, I got this!

Extended channels are now supported and the default for all miners. BM1397 is forced to extended channels — the standard channel option is greyed out for it in the pool settings UI. The coinbase decoder is fully functional for extended channels, providing full coinbase visibility on the dashboard (block height, payout addresses, reward value).

Standard channels are available as an option for all other ASICs (not BM1397). Ntime rolling has been removed from standard channels — they rely solely on version rolling. This means standard channels will produce duplicated shares for now, since the firmware doesn't yet utilize the full version mask search space. Standard channels are a good tool for now to test and optimize the version rolling implementation of the ASIC miners that could utilize it fully. Once version rolling covers the full 32² and 16² search room, standard channels should no longer produce duplicates.

Extended and Standard Channels works both on SRI reference server, and on my own typescript implementation following SRI as near as possible. Regtests were done to proof fully functional operation:

Bildschirmfoto_20260220_201036 Bildschirmfoto_20260220_201008 Bildschirmfoto_20260220_200919

What we can discuss is, to bring back ntime rolling for testing purpose, cap it for standard channels, until full hardware utilization of version_rolling is working.

Current situation for standard channels, we only have nonce on so at ~1 TH/s: we would be exhausted in ~4.3 ms
With full 16² version_rolling situation, at ~1 TH/s: ~281 seconds which is already cool
If Bitaxe would reach arround 4-5TH, this would already get problematic with pools that sends jobs every 60sec
So we would need ntime rolling sooner or later and use a savetycap that we dont break consensus

@adammwest
Copy link
Contributor

For those unfamiliar, the network constraint for ntime is

[median past time, consensus time + 7200s]
the 5th last blocks ntime in the past and 2 hours into the future

Interestingly its a growing constraint so if we have no block for 1 hour our forward constraint grows to 3 hours

sources

@bitaxeorg bitaxeorg deleted a comment from Notmyprob487-png Feb 23, 2026
@bitaxeorg bitaxeorg deleted a comment from Notmyprob487-png Feb 23, 2026
@bitaxeorg bitaxeorg deleted a comment from Notmyprob487-png Feb 23, 2026
@bitaxeorg bitaxeorg deleted a comment from warioishere Feb 23, 2026
@bitaxeorg bitaxeorg deleted a comment from warioishere Feb 23, 2026
@bitaxeorg bitaxeorg deleted a comment from BlockBitOfficial Feb 23, 2026
@bitaxeorg bitaxeorg deleted a comment from BlockBitOfficial Feb 23, 2026
@bitaxeorg bitaxeorg deleted a comment from BlockBitOfficial Feb 23, 2026
@bitaxeorg bitaxeorg deleted a comment from BlockBitOfficial Feb 23, 2026
@bitaxeorg bitaxeorg deleted a comment from BlockBitOfficial Feb 23, 2026
@bitaxeorg bitaxeorg deleted a comment from WantClue Feb 23, 2026
@bitaxeorg bitaxeorg deleted a comment from warioishere Feb 23, 2026
@bitaxeorg bitaxeorg deleted a comment from benjamin-wilson Feb 23, 2026
@bitaxeorg bitaxeorg deleted a comment from warioishere Feb 23, 2026
@bitaxeorg bitaxeorg deleted a comment from warioishere Feb 23, 2026
@bitaxeorg bitaxeorg deleted a comment from warioishere Feb 23, 2026
@bitaxeorg bitaxeorg deleted a comment Feb 23, 2026
@bitaxeorg bitaxeorg deleted a comment Feb 23, 2026
@bitaxeorg bitaxeorg deleted a comment Feb 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants