Skip to main content
thrufmt is the standard human-readable form for Thru public addresses (ta…) and signatures (ts…). It defines how raw binary keys and signatures are encoded, how checksums are added, and how clients should validate them. All clients are expected to match their behavior exactly, byte-for-byte.

CLI Usage

Use thru-cli util convert to convert between hex and thrufmt. Convert a 32-byte hex public key to ta…:
$ thru-cli --json util convert pubkey hex-to-thrufmt \
0000000000000000000000000000000000000000000000000000000000000001
{
  "hex_pubkey": "0000000000000000000000000000000000000000000000000000000000000001",
  "thru_pubkey": "taAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEB"
}
Convert a 64-byte hex signature to ts…:
$ thru-cli --json util convert signature hex-to-thrufmt \
0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
{
  "hex_signature": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
  "thru_signature": "tsASNFZ4mrze8BI0VniavN7wEjRWeJq83vASNFZ4mrze8BI0VniavN7wEjRWeJq83vASNFZ4mrze8BI0VniavN7x4A"
}
Drop --json for the plain-text output. Note that inverse conversions (thrufmt-to-hex) for both addresses and signatures are also supported.

Base Encoding

Thru streams raw bytes into a base64url encoder (RFC 4648 §5). The alphabet is:
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_
  • The stream never uses padding (=).
  • Encoding starts with a two-character type prefix (ta or ts) so handles can be visually distinguished.
  • All checksums are computed on the binary payload before base64 encoding.

Public Address Format (ta…)

Encoding turns a 32-byte public key into 46 printable characters (ta + 44 base64url symbols).

Encoding

  1. All buffers begin with ta to flag the string as a Thru account.
  2. Stream the 32 raw public-key bytes into the base64url accumulator, while updating a byte sum.
  3. Take the sum modulo 256 (2^8) and append the single checksum byte, giving 33 total bytes.
  4. Flush the accumulator to base64url characters without padding. Those 33 bytes always expand to 44 characters, so the finished string is 46 characters long (ta + 44 base64 symbols).

Checksum

checksum = (Σ pubkey[i]) & 0xFF
Decoding recomputes the sum from the decoded 32 bytes, masks it to 8 bits, and requires it to match the appended checksum byte. Any mismatch results in a decoding error, preventing truncated or mistyped addresses from being accepted.

Signature Format (ts…)

Encoding serializes a 64-byte Ed25519 signature into a 90-character string (ts + 88 base64url symbols).

Encoding

  1. All buffers begin with ts to flag the string as a Thru signature.
  2. Stream all 64 signature bytes through the base64url accumulator, while updating a running checksum.
  3. Take the sum modulo 65,536 (2^16) and append the two checksum bytes in big-endian order. That turns the payload into 66 bytes (64 data + 2 checksum).
  4. Flush the accumulator to base64url characters. Sixty-six bytes always become 88 characters, resulting in a fixed 90-character ts… string.

Checksum

checksum = (Σ signature[i]) & 0xFFFF
Decoding expects a 90-character string starting with ts. After base64url decoding it verifies the checksum word from the last two bytes before returning the 64-byte signature.