← Book map

Chapter 11 · Platform

Describing, not building

One interface file, field by field — plus the script classes that actually do transaction-shaped work. The chapter's value is the boundary: this library describes, wallets build.

Where transactions are actually built The primitives library describes raw transaction shapes and scripts; a wallet or daemon RPC builds and signs the transaction that reaches the chain. DESCRIBE ≠ BUILD this library shapes + deserialisers wallet / RPC client builds, signs, broadcasts verusd validates, mines chain state RawTransaction is the JSON shape the daemon returns — useful for reading, not for composing.

FIGURE 11.1 · The boundary the library sits on.

The file, field by field

src/transaction/RawTransaction.ts is 24 lines and every one of them is a field. Read it as a decoder map for getrawtransaction output, not as a builder:

FieldTypeWhat it tells you
hexstringThe serialised transaction — the only field a node will accept back
txidstringDouble-SHA256 of the transaction, byte-reversed for display
overwinteredbooleanWhether the Zcash-era Overwinter format applies
version / versiongroupidnumber / stringFormat generation. Verus inherits Zcash's version-group scheme, which is why both exist
locktime, expiryheightnumberEarliest spend height, and the height after which the tx is no longer valid
vin / voutApiPrimitive[]Inputs and outputs — deliberately untyped here (see below)
vjoinsplit, vShieldedSpend, vShieldedOutput, bindingSigarrays / stringThe shielded half of the format; empty on transparent transactions
valueBalance / valueBalanceZatnumberNet shielded value, in VRSC and in zats
blockhash, height, confirmations, time, blocktimeoptionalPresent only when the tx is confirmed and the node was asked for block context

Why vin and vout are untyped

They are Array<ApiPrimitive> — a permissive type covering the JSON shapes the daemon returns for a scriptSig, a scriptPubKey, a reserve transfer output, an identity output. Typing every output shape would mean mirroring the daemon's entire RPC schema; the library deliberately does not. The practical consequence: you can read a transaction confidently, and you should not construct one from these types.

What the library does give you for transactions

The script layer, under pbaas/transaction/:

ClassShapeUsed by
VerusScriptchunks: ScriptChunk[]; buffer ⇄ chunks via compile/decompileAny output script; throws "Cannot deserialize a truncated script push" on a bad read
SmartTransactionScriptSmart-transaction output scriptReserve transfers and PBaaS operations
IdentityScriptIdentity-bearing output scriptIdentity registration and updates

VerusScript is the one to read: fromBuffer decompiles a slice into chunks and refuses a truncated push, which is the same class of error you would otherwise only see as an invalid script on the node.

The honest boundary

There is no input selection, no fee estimation, no signing loop, no toHex() for a transaction you assembled. In the reference applications built on this library, transaction construction happens in the wallet and in the provisioning webhook's RPC calls (registernamecommitment, registeridentity) — not in this package. When a task says "build a tx", the work is elsewhere; this library's job is the object that goes inside it.

If you find yourself writing offsets for a transaction here, you have taken a wrong turn — you should be calling the daemon, or using the fork that extends this package.

Reading the code

src/transaction/RawTransaction.ts          # the whole directory
src/pbaas/transaction/VerusScript.ts       # chunks ⇄ script bytes
src/pbaas/transaction/SmartTransactionScript.ts
src/pbaas/transaction/IdentityScript.ts
src/utils/script.ts                        # compile() / decompile()
src/utils/pushdata.ts                      # OP_PUSHDATA encoding