TRANSACTION v2
Transfer-only, deterministic signing.
PBE 0.0.1 accepts one transaction type: transfer. The optional payment reference is serialized and signed, making it safe to bind an order to a transfer.
JSON fields
| Field | Encoding / meaning |
|---|---|
| version | 2 |
| networkId | 1 |
| type | 1 = transfer |
| senderPublicKey | 32-byte Ed25519 public key, hex |
| senderAddress | pbe address derived from sender public key |
| nonce | Unsigned integer string; next confirmed outgoing nonce |
| fee | Unsigned base-unit integer string |
| timestamp | Unix seconds as unsigned integer string |
| payload.recipient | Mainnet PBE address |
| payload.amount | Positive base-unit integer string |
| payload.paymentReference | Optional signed reference, max 64 bytes |
| signature | 64-byte Ed25519 signature, hex |
Unsigned serialization
Binary
u16(version=2)
u32(networkId=1)
u16(type=1)
32 bytes senderPublicKey
text(senderAddress) // u32 byte length + UTF-8 bytes
u64(nonce)
u64(fee)
u64(timestamp)
varBytes(transferPayload)
transferPayload =
text(recipient)
u64(amount)
text(paymentReference) // empty text when absentSignature and TXID
Protocol
signingHash = SHA256("PBE:TX:V1\0" || unsignedBytes)
signature = Ed25519.sign(signingHash, senderPrivateKey)
txid = SHA256(unsignedBytes || signature)The signing-domain string remains PBE:TX:V1\0; it is a domain separator, not the transaction format number.
Minimum fee
Base units
minimumFee = 1000 + (signedTransactionByteLength × 2)Applications should serialize once with a zero/provisional fee to estimate size, calculate the required fee, rebuild, sign, then broadcast.
Address derivation
Protocol
payload = first 20 bytes of SHA256(ed25519PublicKey)
address = Bech32m(hrp="pbe", payload)Private keysNever send private keys, seed material, wallet passwords or decrypted PKCS#8 bytes to an RPC node. Sign locally.
