Skip to main content

Horizen (ZEN)

Reference metadata for Horizen. The chain is discontinued and every call that carries its chainId is rejected — the facts below describe the contract as it stood before the shutdown.

FieldValue
coinType121
keyPathm/44'/121'/<accountIdx>'/0/0
amount unitzatoshi (1 ZEN = 1e8)
chainIdbip122:0007104ccda289427919efc39dc9e4d4/slip44:121

Supported Methods

MethodSupported
getAddress
signTransaction
signMessage
signTypedData
signAuthEntry

Notes

Discontinued. The native ZEN chain shut down on 2025-07-23, when ZEN migrated to an ERC-20 token on Base; both the legacy mainchain and the EON EVM chain were retired. signTransaction for this chainId is no longer supported. ZEN on Base is an ordinary ERC-20 and uses the Ethereum-family path (eip155:8453/slip44:60). The description below is kept for historical reference only. Formerly a fully signable UTXO chain forked from Zcash. Transparent addresses with a 2-byte version prefix (zn... / zs...) and CHECKBLOCKATHEIGHT replay protection that binds each output to a recent block height. Legacy addresses only, no SegWit. Shares the Bitcoin-family signTransaction path; provide the previous transactions for the inputs you spend.

option (BIP-115 replay protection)

Horizen output scripts are BIP-115 (CHECKBLOCKATHEIGHT): the device appends <block hash><height> to every output script. The signer has no network access, so the app must supply this value via transaction.option — unlike a fixed chain ID, no static wallet default can exist here because it depends on the current chain tip.

FieldTypeRequiredSourceNotes
option.blockHashhex (64 chars)RequiredAppExactly as shown by a block explorer (display byte order) — the wallet reverses the bytes internally before signing.
option.heightnumberRequiredAppHeight of the same block as blockHash. DCENT's own app uses tip − 200 to avoid reorgs — Apps should keep a similar margin.
danger

The wallet only guarantees correct encoding of whatever blockHash/height you pass — it cannot verify that block actually exists on-chain. A wrong-but-well-formed pair signs successfully and is only rejected at broadcast, which makes the root cause hard to trace. Omitting option entirely is caught earlier: the device rejects with bip115 opt size too small: 0.

Already have the encoded bytes? A hex string is also accepted: <block hash, 32 bytes, byte-reversed><height, little-endian> — even length, no 0x prefix, no length prefix (the device adds that itself). Any other shape — object or string — is rejected with -32602.

danger

Everything below is the contract as it stood before the chain shut down. Horizen's chainId is on the bridge's discontinued list, so every call that carries it — getAddress included — is rejected with unsupported_method before the method is even dispatched. The payload shapes are kept for historical reference only.

Horizen used the Bitcoin-family signing path: the signTransaction payload shape (inputs, outputs, previous transactions) matched the Bitcoin reference, and only the address version, coinType and amount decimals differed.

signTransaction

await dcent.sign({
method: 'signTransaction',
chainId: 'bip122:0007104ccda289427919efc39dc9e4d4/slip44:121',
payload: {
keyPath: "m/44'/121'/0'/0/0",
transaction: {
inputs: [
{ rawTransaction: '<prev tx hex>', index: 0, txType: 'p2pkh', keyPath: "m/44'/121'/0'/0/0" }
],
outputs: [
{ txType: 'p2pkh', amount: '990000', addresses: ['<zn... recipient>'] }
],
option: { blockHash: '<64 hex, display byte order>', height: 1899800 }
}
}
}) // → body.parameter.signature

signTransaction — full field reference

FieldTypeRequiredSourceUnitNotes
inputs[].rawTransactionhexRequired-RealWalletFull prev-tx hex of the UTXO; must be device-owned
inputs[].indexnumberRequiredAppUTXO output index
inputs[].txTypeenumRequiredAppAlways p2pkh — Horizen has no SegWit variant
inputs[].keyPathstringRequired-RealWalletPath that signs this input
inputs[].sequencenumberOptionalAppSame defaulting behavior as Bitcoin (0xfffffffd for RBF-enabled coins when omitted)
outputs[].amountstringRequiredAppzatoshiOutput value
outputs[].addressesstring[]Required-RealAppRecipient. Only addresses[0] is used, exactly one non-change output allowed — use a second output with txType: 'change' for change.
optionobject | hexRequiredAppBIP-115 replay-protection tail — sub-field breakdown above.