Community release

Pay with NIM when there is no internet

NIMmesh, a Bluetooth mesh wallet for Nimiq, goes to alpha today. You sign a payment on a phone with no connection, and it hops phone to phone until one of them is online and puts it on the chain for you.

How the mesh works

Every phone running NIMmesh is a node. The internet is needed at the final hop only.

A node signs, carries and relays. A relay never reads what it carries, and it holds a payment until another node appears, so the mesh can be sparse. Only the last phone in the chain needs the internet, and the person holding it never sees what passed through.

What makes all of this possible is one number: the size of a NIM payment.

Today it goes to alpha. The Android app is built and sealed with its permanent signing key, so a phone can verify that every future update comes from the same author. The first testers come from the Nimiq community, on their own phones.

iOS Control Center with Wi-Fi not connected, Cellular Data off and Bluetooth on
No Wi-Fi, no cell data. Bluetooth on.
NIMmesh home screen, footer reads mesh offline, 0 nearby
Alone: mesh offline, 0 nearby.
NIMmesh home screen, footer reads mesh meshed, 1 nearby
A peer appears: mesh meshed, 1 nearby.
A second phone running NIMmesh with Wi-Fi on, footer also reads mesh meshed, 1 nearby
The other phone sees it too. This one has Wi-Fi: the gateway.

Exactly 139 bytes

Every field is fixed width. The biggest payment ever and the smallest are the same size.

Not on average, every single one. Sending a fortune takes exactly as many bytes as sending one cent.

That matters more than being small. A radio either fits it or it does not, once, forever. No rare case that breaks in a field with no signal.

cryptography, 96 B the payment, 40 B format, 3 B

Tap a field. 96 of the 139 bytes are the public key and the signature. The payment itself is 40. The three slivers are single-byte fields: format, proof type, network id.

One packet on every radio

Attach a note to the payment and it stops fitting in a text message.

#
Transport
Filled
Room left
01
Binary SMS140 B, GSM 03.38 at 8-bit
99%
1 byte
02
Meshtastic packet221 B usable, the conservative reading
63%
82 bytes
03
Raw LoRa frame255 B, SX126x explicit header
55%
116 bytes
04
Bluetooth LE block256 B, the smallest we pad to
54%
117 bytes

SMS is the tight one: a bare payment fits with one byte to spare. Attach a note (a memo, in Nimiq terms) and it grows to roughly 205 bytes, which no single SMS can carry. SMS moves payments, not notes.

NIM versus Bitcoin on the air

Both existing Bitcoin bridges split the transaction and rebuild it at the far end. NIMmesh never does.

A NIM payment139 bytes, every time
travels in one piece on chain
A Bitcoin paymentsplit into pieces
12345+… rebuilt, then chain
ProjectHow it goes on the airWhat that forces
btcmesh Chunked hexadecimal strings over LoRa direct messages. A reassembler on the receiving end, and a configurable reassembly timeout for when a chunk never lands.
MeshtasticBitcoinCore_Bridge You divide the raw hex yourself into portions of 200 characters or less. A + before every portion and a == to terminate. Its README notes that Bitcoin hex may run past 1,000 characters against a 228-byte buffer.

Two costs compound there. A Bitcoin transaction is larger to begin with, and both projects send it as a hexadecimal string, which doubles the byte count before it ever reaches the radio.

Meshtastic's PRIVATE_APP port carries raw bytes, so NIMmesh puts 139 binary bytes on the air and they stay 139 binary bytes. One packet. Delivered or not delivered, with no third state in between.

A Bitcoin transaction has no single size, it grows with the number of coins it spends. The advantage is not that a NIM payment is smaller. It is that its size is fixed: no reassembly code, no partial state, no timeout to tune.

What is already on chain

Four mainnet payments totalling 19 NIM, each one readable on the block explorer.

Each block carries exactly one transaction, at the value shown, and each is checkable on the block explorer.

BlockWhenValueWhat it proved
55488525 7 Jul 2026, 00:38 UTC 1 NIM A phone in airplane mode paid over Bluetooth to a Mac acting as the gateway. The first one that was real money.
56054933 13 Jul 2026, 11:39 UTC 1 NIM Phone to phone, with no computer anywhere in the path. An iPhone in airplane mode relayed through a second phone that had data.
56055090 13 Jul 2026, 11:42 UTC 15 NIM The same path again, three minutes later, at fifteen times the amount.
56055105 13 Jul 2026, 11:42 UTC 2 NIM And once more, fifteen seconds after that.

These prove the Bluetooth path end to end, with real funds. They prove nothing about LoRa or SMS, which have never carried a payment.

What is not proven

The measurement is done. The radio work is not.

The five unproven claimsA LoRa payment, an SMS payment, the 1.35 s airtime figure, Android over the air, and the mainnet swap.
ClaimStatusWhat is true today
A payment over LoRa Unproven No radio has ever carried one. The Meshtastic frame codec is written and checked byte by byte against the published protobuf schema by hand, but no LoRa hardware has been bought and nothing has been on the air.
A payment over SMS Unproven The one byte of headroom is arithmetic, not a delivery receipt. No transaction has been sent through a carrier.
1.35 seconds on air Computed Derived from Semtech's time-on-air formula for a 155-byte frame at the LongFast preset. Not measured on a device.
Android relaying Unproven Both Bluetooth roles come up on a real stack and the wallet signs correctly on device. No byte has yet crossed the air between two Android phones.
Cross-chain swaps Testnet NIM to USDC runs end to end and settles, on Nimiq testnet and Polygon Amoy only. The mainnet phone-to-phone swap has never been run. Do not read the swap code as mainnet proven.

Talking to Bitchat

The two meshes already carry each other's messages, phone to phone.

NIMmesh is a Nimiq take on Bitchat, the Bluetooth mesh messenger Jack Dorsey built over a weekend in July 2025. Same mesh, same store and forward, but the thing being carried is a signed transaction instead of a chat message.

The two speak the same wire format, so they carry each other's traffic. A NIMmesh message shows up in real Bitchat, and a Bitchat message shows up in NIMmesh. This is the part I most want to keep pushing on, and it is why this stays a community project, not a product. A mesh is only worth anything if other people's software is on it.

Stated as reported, not verified here: the interoperability demo was run phone to phone with no computer in the path. The compatibility layer is 492 lines of Swift in the repository. Two phones in a room are the only real proof, and you cannot check that from a blog post.

Roadmap

A transport seam first, then a radio on a mesh somebody already runs.

Today NIMmesh speaks only Bluetooth, and the code assumes Bluetooth everywhere. The next piece of work is making the radio swappable, so LoRa and SMS plug in without rewriting the app.

DONE
Meshtastic frame codec
Written and checked byte by byte against the published schema. No hardware needed.
NEXT
The transport seam
Bluetooth becomes one implementation of a trait instead of an assumption.
THEN
LoRa on a community mesh
Two $35 radios. An existing community network supplies every hop in between.
THEN
Binary SMS
Cell signal but no data. The transport that needs no hardware at all.

After that, LoRa. Not by building a network. Meshtastic communities already run open meshes across many cities, maintained and powered by people who have nothing to do with Nimiq. One $35 radio puts a NIMmesh gateway on one.

An earlier post on this blog found 143 million crypto owners in markets where no exchange sells NIM. Buying is one kind of reach. Paying is another, and a payment that fits in a single SMS does not care which exchanges serve your country.

The alpha starts with testers from the Nimiq community. The milestone that matters next is simple: a payment crossing a phone that belongs to somebody I have never met. That will be the next post.

All of it is open source, Apache 2.0, at github.com/Andjroo111/nimmesh. The 139-byte tests quoted above run in its CI.

How the 139 bytes were measuredThe five tests, the constant that disagrees with itself, and why the number cannot drift.

The size is asserted in CI, in a file called transport_mtu_tests. A change to the wire format turns the build red instead of failing silently in a field somewhere. Five tests, all passing when this post was written:

TestWhat it asserts
a_real_signed_transfer_is_exactly_the_advertised_139_bytesA fully formed, signed transfer serialises to 139 bytes.
a_transaction_fits_one_meshtastic_packet_with_room_to_spareIt fits, and the margin is at least 64 bytes, so a slow creep toward the ceiling is caught early rather than at the edge.
a_transaction_fits_a_single_binary_smsIt fits inside 140 bytes with no concatenation header.
a_transaction_fits_the_transports_we_already_ship_or_planIt fits the Bluetooth padding block and a raw LoRa frame.
the_sms_headroom_is_exactly_one_byte_and_that_is_documentedThe headroom is one byte, so if it ever loosens or tightens the documentation is wrong and has to be corrected.

The transaction under test is built with the largest values its fields can hold: the maximum amount, the maximum fee, the highest block height. If any integer were serialised short, the test would measure a smaller number and the claim would quietly shrink. It is measured from a real serialised transaction rather than compared against a stored constant, because a stale constant is exactly how a real regression gets waved through.

The Meshtastic ceiling is quoted three different ways, and the post takes the smallest. Meshtastic's own mesh.proto defines DATA_PAYLOAD_LEN = 233, noting that the 16-byte header sits outside that envelope. Our test uses a 237-byte packet and subtracts the 16-byte header anyway, giving 221. So the honest range for room left is somewhere between 82 and 94 bytes. This post uses 82, the most conservative reading. The argument does not need the extra twelve bytes, and a claim that survives its own worst case is worth more than one that does not.

Read nextWhere NIM cannot be purchased AlsoNimiq’s treasury, 2018 to 2026

Help fund more development

Built for the Nimiq community.

Any help means a lot, and it goes straight back into building.

NIM