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.
| Field | Value |
|---|---|
| coinType | 121 |
| keyPath | m/44'/121'/<accountIdx>'/0/0 |
| amount unit | zatoshi (1 ZEN = 1e8) |
| chainId | bip122:0007104ccda289427919efc39dc9e4d4/slip44:121 |
Supported Methods
| Method | Supported |
|---|---|
| getAddress | ✗ |
| signTransaction | ✗ |
| signMessage | ✗ |
| signTypedData | ✗ |
| signData | ✗ |
| signAuthEntry | ✗ |
Notes
Discontinued. This chainId is on the bridge's discontinued-chain list, so every call that carries it and reaches the bridge is rejected with 4200 (unsupported_method); the connector's own argument checks (e.g. a missing keyPath) still apply first. 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 (DCENT X firmware) 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.
| Field | Type | Required | Source | Notes |
|---|---|---|---|---|
option.blockHash | hex (64 chars) | Required | App | Exactly as shown by a block explorer (display byte order) — the wallet reverses the bytes internally before signing. |
option.height | number | Required | App | Height of the same block as blockHash. DCENT's own app uses tip − 200 to avoid reorgs — Apps should keep a similar margin. |
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.
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 (DCENT X adds that itself). Other shapes were rejected with -32602 (an empty string or null was treated as no option).
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 and reaches the bridge — getAddress included — is rejected with unsupported_method (4200) before the method is dispatched; the connector's own argument checks still run first. 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, except for the address version, coinType and the BIP-115 option.
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
| Field | Type | Required | Source | Unit | Notes |
|---|---|---|---|---|---|
inputs[].rawTransaction | hex | Required-Real | Wallet | — | Full prev-tx hex of the UTXO; must be device-owned |
inputs[].index | number | Required | App | — | UTXO output index |
inputs[].txType | enum | Required | App | — | Always p2pkh — Horizen has no SegWit variant |
inputs[].keyPath | string | Required-Real | Wallet | — | Path that signs this input |
inputs[].sequence | number | Optional | App | — | When omitted, no sequence is sent and DCENT X then uses 0xffffffff (only Bitcoin mainnet defaults to 0xfffffffd, opt-in RBF). |
outputs[].amount | string | Required | App | zatoshi | Output value |
outputs[].addresses | string[] | Required-Real | App | — | Recipient. Only addresses[0] is signed (later entries are not signed, but a Bitcoin Taproot address (bc1p… / tb1p…) among them is rejected with -32602 — send a single address), exactly one non-change output allowed — use a second output with txType: 'change' for change. The change output's addresses[0] is a BIP-32 derivation path on your own account (for example m/44'/121'/0'/1/0), not an address — the device derives the change address from that path itself. Use a path on the account you are signing with; the full rule is on the Bitcoin page. |
option | object | hex | Required | App | — | BIP-115 replay-protection tail — sub-field breakdown above. |