From c5983f3aa7fd15daef79df28d251e4d344a13a4b Mon Sep 17 00:00:00 2001 From: highlander Date: Mon, 23 Mar 2026 15:26:11 -0600 Subject: [PATCH 01/15] feat(zcash): add Orchard shielded transaction protocol MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - PCZT streaming protocol: ZcashSignPCZT, ZcashPCZTAction, ZcashPCZTActionAck - Orchard FVK: ZcashGetOrchardFVK, ZcashOrchardFVK - Transparent shielding: ZcashTransparentInput, ZcashTransparentSig - Wire IDs 1300-1307 - nanopb options for all fields Multi-phase protocol: session init → action streaming → transparent signing. Supports on-device Orchard digest verification via sub-digest fields. --- messages-zcash.options | 33 +++++++++ messages-zcash.proto | 150 +++++++++++++++++++++++++++++++++++++++++ messages.proto | 9 +++ 3 files changed, 192 insertions(+) create mode 100644 messages-zcash.options create mode 100644 messages-zcash.proto diff --git a/messages-zcash.options b/messages-zcash.options new file mode 100644 index 00000000..c1d904a0 --- /dev/null +++ b/messages-zcash.options @@ -0,0 +1,33 @@ +ZcashSignPCZT.address_n max_count:8 +ZcashSignPCZT.pczt_data max_size:4096 +ZcashSignPCZT.header_digest max_size:32 +ZcashSignPCZT.transparent_digest max_size:32 +ZcashSignPCZT.sapling_digest max_size:32 +ZcashSignPCZT.orchard_digest max_size:32 +ZcashSignPCZT.orchard_anchor max_size:32 + +ZcashPCZTAction.alpha max_size:32 +ZcashPCZTAction.sighash max_size:32 +ZcashPCZTAction.cv_net max_size:32 +ZcashPCZTAction.nullifier max_size:32 +ZcashPCZTAction.cmx max_size:32 +ZcashPCZTAction.epk max_size:32 +ZcashPCZTAction.enc_compact max_size:52 +ZcashPCZTAction.enc_memo max_size:512 +ZcashPCZTAction.enc_noncompact max_size:612 +ZcashPCZTAction.rk max_size:32 +ZcashPCZTAction.out_ciphertext max_size:80 + +ZcashSignedPCZT.signatures max_count:64 max_size:64 +ZcashSignedPCZT.txid max_size:32 + +ZcashGetOrchardFVK.address_n max_count:8 + +ZcashOrchardFVK.ak max_size:32 +ZcashOrchardFVK.nk max_size:32 +ZcashOrchardFVK.rivk max_size:32 + +ZcashTransparentInput.sighash max_size:32 +ZcashTransparentInput.address_n max_count:8 + +ZcashTransparentSig.signature max_size:73 diff --git a/messages-zcash.proto b/messages-zcash.proto new file mode 100644 index 00000000..4f47c245 --- /dev/null +++ b/messages-zcash.proto @@ -0,0 +1,150 @@ +/* + * Messages (Zcash specific) for KeepKey Communication + * + * Zcash shielded transaction signing via PCZT (Partially Constructed + * Zcash Transaction) format. Supports Orchard spend authorization. + */ + +syntax = "proto2"; + +// Sugar for easier handling in Java +option java_package = "com.keepkey.deviceprotocol"; +option java_outer_classname = "KeepKeyMessageZcash"; + +/** + * Request: Sign a Zcash shielded transaction (PCZT format) + * + * The PCZT contains pre-constructed transaction data with proofs. + * The device derives spend authorization keys, computes the sighash, + * and returns RedPallas signatures for each Orchard action. + * + * @next ZcashPCZTActionAck + * @next Failure + */ +message ZcashSignPCZT { + repeated uint32 address_n = 1; // ZIP-32 derivation path [32', 133', account'] + optional uint32 account = 2; // Account index (alternative to full path) + optional bytes pczt_data = 3; // Serialized PCZT data (may be chunked) + optional uint32 n_actions = 4; // Number of Orchard actions to sign + optional uint64 total_amount = 5; // Total ZEC amount (zatoshis) for user confirmation + optional uint64 fee = 6; // Transaction fee (zatoshis) + optional uint32 branch_id = 7; // Consensus branch ID + // Phase 2a: sub-digests for on-device sighash computation + optional bytes header_digest = 8; // 32-byte pre-computed header digest + optional bytes transparent_digest = 9; // 32-byte transparent digest (or empty) + optional bytes sapling_digest = 10; // 32-byte sapling digest (or empty) + optional bytes orchard_digest = 11; // 32-byte orchard digest + // Phase 2b: bundle metadata for orchard digest verification + optional uint32 orchard_flags = 12; // Orchard bundle flags byte + optional int64 orchard_value_balance = 13; // Orchard value balance (LE i64) + optional bytes orchard_anchor = 14; // 32-byte orchard anchor + // Phase 3: transparent shielding support + optional uint32 n_transparent_inputs = 30; // 0 for shielded-only (default), >0 for hybrid shielding tx +} + +/** + * Per-action signing data extracted from PCZT. + * Sent as individual messages for streaming large transactions. + * + * @next ZcashSignedPCZT + * @next ZcashPCZTActionAck + * @next Failure + */ +message ZcashPCZTAction { + optional uint32 index = 1; // Action index within the Orchard bundle + optional bytes alpha = 2; // 32-byte spend authorization randomizer + optional bytes sighash = 3; // 32-byte transaction sighash (ZIP 244) - legacy mode + optional bytes cv_net = 4; // 32-byte value commitment + optional uint64 value = 5; // Action value in zatoshis (for display) + optional bool is_spend = 6; // True if this action spends a note + // Phase 2b: action fields for incremental orchard digest verification + optional bytes nullifier = 7; // 32-byte nullifier + optional bytes cmx = 8; // 32-byte note commitment + optional bytes epk = 9; // 32-byte ephemeral key + optional bytes enc_compact = 10; // 52-byte compact encrypted note + optional bytes enc_memo = 11; // 512-byte encrypted memo + optional bytes enc_noncompact = 12; // Remaining encrypted note bytes + optional bytes rk = 13; // 32-byte randomized verification key + optional bytes out_ciphertext = 14; // 80-byte output ciphertext +} + +/** + * Response: Acknowledgment requesting next action data + * + * @prev ZcashSignPCZT + * @prev ZcashPCZTAction + */ +message ZcashPCZTActionAck { + optional uint32 next_index = 1; // Index of next action to process +} + +/** + * Response: Signed PCZT with spend authorization signatures + * + * @prev ZcashPCZTAction + */ +message ZcashSignedPCZT { + repeated bytes signatures = 1; // 64-byte RedPallas signatures, one per action + optional bytes txid = 2; // 32-byte computed transaction ID +} + +/** + * Request: Get the Orchard Full Viewing Key for a given account. + * + * The FVK (ak, nk, rivk) is safe to export - it allows viewing + * transactions but cannot spend funds. Used to construct unified addresses. + * + * @next ZcashOrchardFVK + * @next Failure + */ +message ZcashGetOrchardFVK { + repeated uint32 address_n = 1; // ZIP-32 derivation path [32', 133', account'] + optional uint32 account = 2; // Account index (alternative to full path) + optional bool show_display = 3; // Show on device display +} + +/** + * Response: Orchard Full Viewing Key components. + * + * ak = [ask]G on Pallas curve (serialized point, 32 bytes) + * nk = nullifier deriving key (32 bytes) + * rivk = commitment randomness key (32 bytes) + * + * @prev ZcashGetOrchardFVK + */ +message ZcashOrchardFVK { + optional bytes ak = 1; // 32-byte authorizing key (Pallas point) + optional bytes nk = 2; // 32-byte nullifier deriving key + optional bytes rivk = 3; // 32-byte commitment randomness key +} + +/** + * Request: Transparent input data for hybrid shielding transactions. + * Sent one per transparent input during the transparent signing phase. + * The device ECDSA-signs the per-input sighash with the secp256k1 key + * at the provided BIP44 path. + * + * Flow: after ZcashSignPCZT with n_transparent_inputs > 0, the device + * responds with ZcashPCZTActionAck. For each transparent input, the host + * sends ZcashTransparentInput and receives ZcashTransparentSig. After + * all transparent inputs, the device transitions to the Orchard phase. + * + * @next ZcashTransparentSig + * @next Failure + */ +message ZcashTransparentInput { + required uint32 index = 1; // Input index within the transaction + required bytes sighash = 2; // 32-byte per-input sighash (host-computed, ZIP-244) + repeated uint32 address_n = 3; // BIP44 path [44', 133', 0', 0, 0] + optional uint64 amount = 4; // Input value in zatoshis (for display verification) +} + +/** + * Response: ECDSA signature for a transparent input. + * + * @prev ZcashTransparentInput + */ +message ZcashTransparentSig { + required bytes signature = 1; // DER ECDSA signature (72-73 bytes) + optional uint32 next_index = 2; // Next transparent input index, or 0xFF = done +} diff --git a/messages.proto b/messages.proto index b26f1b01..7b12d11c 100644 --- a/messages.proto +++ b/messages.proto @@ -203,6 +203,15 @@ enum MessageType { MessageType_MayachainMsgAck = 1204 [ (wire_in) = true ]; MessageType_MayachainSignedTx = 1205 [ (wire_out) = true ]; + // Zcash (Orchard shielded) + MessageType_ZcashSignPCZT = 1300 [ (wire_in) = true ]; + MessageType_ZcashPCZTAction = 1301 [ (wire_in) = true ]; + MessageType_ZcashPCZTActionAck = 1302 [ (wire_out) = true ]; + MessageType_ZcashSignedPCZT = 1303 [ (wire_out) = true ]; + MessageType_ZcashGetOrchardFVK = 1304 [ (wire_in) = true ]; + MessageType_ZcashOrchardFVK = 1305 [ (wire_out) = true ]; + MessageType_ZcashTransparentInput = 1306 [ (wire_in) = true ]; + MessageType_ZcashTransparentSig = 1307 [ (wire_out) = true ]; // TRON MessageType_TronGetAddress = 1400 [ (wire_in) = true ]; MessageType_TronAddress = 1401 [ (wire_out) = true ]; From 4ce26e7278f5e94822e5f5867f16385e488d2cf0 Mon Sep 17 00:00:00 2001 From: highlander Date: Mon, 23 Mar 2026 15:35:41 -0600 Subject: [PATCH 02/15] fix: include messages-zcash.proto in package build scripts --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index ca6eb0ae..b9d2c012 100644 --- a/package.json +++ b/package.json @@ -8,8 +8,8 @@ "scripts": { "clean": "rm -rf ./lib/*.js ./lib/*.ts", "build": "npm run build:js && npm run build:json && npm run build:postprocess", - "build:js": "protoc --plugin=protoc-gen-ts=./node_modules/.bin/protoc-gen-ts --js_out=import_style=commonjs,binary:./lib --ts_out=./lib types.proto messages.proto messages-ethereum.proto messages-eos.proto messages-nano.proto messages-cosmos.proto messages-binance.proto messages-ripple.proto messages-tendermint.proto messages-thorchain.proto messages-osmosis.proto messages-mayachain.proto", - "build:json": "pbjs --keep-case -t json ./types.proto ./messages.proto ./messages-ethereum.proto ./messages-eos.proto ./messages-nano.proto ./messages-cosmos.proto ./messages-binance.proto ./messages-ripple.proto ./messages-tendermint.proto ./messages-thorchain.proto ./messages-osmosis.proto ./messages-mayachain.proto > ./lib/proto.json", + "build:js": "protoc --plugin=protoc-gen-ts=./node_modules/.bin/protoc-gen-ts --js_out=import_style=commonjs,binary:./lib --ts_out=./lib types.proto messages.proto messages-ethereum.proto messages-eos.proto messages-nano.proto messages-cosmos.proto messages-binance.proto messages-ripple.proto messages-tendermint.proto messages-thorchain.proto messages-osmosis.proto messages-mayachain.proto messages-zcash.proto", + "build:json": "pbjs --keep-case -t json ./types.proto ./messages.proto ./messages-ethereum.proto ./messages-eos.proto ./messages-nano.proto ./messages-cosmos.proto ./messages-binance.proto ./messages-ripple.proto ./messages-tendermint.proto ./messages-thorchain.proto ./messages-osmosis.proto ./messages-mayachain.proto ./messages-zcash.proto > ./lib/proto.json", "build:postprocess": "find ./lib -name \"*.js\" -exec sed -i '' -e \"s/var global = Function(\\'return this\\')();/var global = (function(){ return this }).call(null);/g\" {} \\;", "prepublishOnly": "npm run build", "test": "echo \"Error: no test specified\" && exit 1" From 742f17263946802291053a959c4d1cb940f63f0d Mon Sep 17 00:00:00 2001 From: highlander Date: Tue, 24 Mar 2026 19:54:19 -0600 Subject: [PATCH 03/15] feat(zcash): add ZcashDisplayAddress protocol message (IDs 1308/1309) New messages for displaying a Zcash unified address on the device screen with FVK verification. The host provides the UA string and FVK components; the device independently derives FVK from seed and verifies the match before displaying the address with a QR code. - ZcashDisplayAddress (wire_in 1308): address + ak/nk/rivk for verification - ZcashAddress (wire_out 1309): confirmed address after user approval - nanopb options: address max_size:128, key fields max_size:32 --- messages-zcash.options | 8 ++++++++ messages-zcash.proto | 33 +++++++++++++++++++++++++++++++++ messages.proto | 2 ++ 3 files changed, 43 insertions(+) diff --git a/messages-zcash.options b/messages-zcash.options index c1d904a0..a80f1ec3 100644 --- a/messages-zcash.options +++ b/messages-zcash.options @@ -31,3 +31,11 @@ ZcashTransparentInput.sighash max_size:32 ZcashTransparentInput.address_n max_count:8 ZcashTransparentSig.signature max_size:73 + +ZcashDisplayAddress.address_n max_count:8 +ZcashDisplayAddress.address max_size:128 +ZcashDisplayAddress.ak max_size:32 +ZcashDisplayAddress.nk max_size:32 +ZcashDisplayAddress.rivk max_size:32 + +ZcashAddress.address max_size:128 diff --git a/messages-zcash.proto b/messages-zcash.proto index 4f47c245..667721f1 100644 --- a/messages-zcash.proto +++ b/messages-zcash.proto @@ -148,3 +148,36 @@ message ZcashTransparentSig { required bytes signature = 1; // DER ECDSA signature (72-73 bytes) optional uint32 next_index = 2; // Next transparent input index, or 0xFF = done } + +/** + * Request: Display a Zcash unified address on the device screen. + * + * The host provides the unified address string and the FVK components + * (ak, nk, rivk) used to derive it. The device independently derives + * the FVK from the seed and verifies it matches the provided components + * before displaying the address with a QR code. + * + * Security: The device confirms the address belongs to the correct + * seed/account by verifying the FVK. The address itself is host-computed + * (full on-device UA derivation requires Sinsemilla/SWU not yet in firmware). + * + * @next ZcashAddress + * @next Failure + */ +message ZcashDisplayAddress { + repeated uint32 address_n = 1; // ZIP-32 derivation path [32', 133', account'] + optional uint32 account = 2; // Account index (alternative to full path) + optional string address = 3; // Host-computed unified address ("u1...") + optional bytes ak = 4; // 32-byte ak for FVK verification + optional bytes nk = 5; // 32-byte nk for FVK verification + optional bytes rivk = 6; // 32-byte rivk for FVK verification +} + +/** + * Response: Confirmed Zcash address after user approval on device. + * + * @prev ZcashDisplayAddress + */ +message ZcashAddress { + optional string address = 1; // Confirmed unified address +} diff --git a/messages.proto b/messages.proto index 7b12d11c..346653e6 100644 --- a/messages.proto +++ b/messages.proto @@ -212,6 +212,8 @@ enum MessageType { MessageType_ZcashOrchardFVK = 1305 [ (wire_out) = true ]; MessageType_ZcashTransparentInput = 1306 [ (wire_in) = true ]; MessageType_ZcashTransparentSig = 1307 [ (wire_out) = true ]; + MessageType_ZcashDisplayAddress = 1308 [ (wire_in) = true ]; + MessageType_ZcashAddress = 1309 [ (wire_out) = true ]; // TRON MessageType_TronGetAddress = 1400 [ (wire_in) = true ]; MessageType_TronAddress = 1401 [ (wire_out) = true ]; From 41be377d9f84edb6b0483a1c21156c9472e9c24e Mon Sep 17 00:00:00 2001 From: highlander Date: Tue, 24 Mar 2026 20:11:15 -0600 Subject: [PATCH 04/15] docs(zcash): clarify ZcashDisplayAddress verification scope MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The device only verifies the Orchard FVK — it cannot verify transparent or Sapling receivers that may also be bundled in a Unified Address. Updated proto comments to explicitly state the guarantee: "This UA contains an Orchard receiver from this account" rather than implying full address ownership. Also clarified that account or address_n is required (no silent fallback to account 0). --- messages-zcash.proto | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/messages-zcash.proto b/messages-zcash.proto index 667721f1..4eaf7dd2 100644 --- a/messages-zcash.proto +++ b/messages-zcash.proto @@ -157,20 +157,31 @@ message ZcashTransparentSig { * the FVK from the seed and verifies it matches the provided components * before displaying the address with a QR code. * - * Security: The device confirms the address belongs to the correct - * seed/account by verifying the FVK. The address itself is host-computed - * (full on-device UA derivation requires Sinsemilla/SWU not yet in firmware). + * VERIFICATION SCOPE: The device only verifies that the Orchard FVK + * (ak, nk, rivk) in this request matches what it derives from the seed + * at the given account. A Unified Address may bundle receivers from + * multiple pools (transparent, Sapling, Orchard). The device CANNOT + * verify non-Orchard receivers — the guarantee is limited to: + * "This UA contains an Orchard receiver from this account." + * It does NOT guarantee that transparent or Sapling receivers (if + * present) are also controlled by this device. + * + * Full on-device UA derivation (Sinsemilla + SWU hash-to-curve) + * is planned for a future firmware release. + * + * Either account or a complete address_n path is REQUIRED. + * The device will reject requests that omit both. * * @next ZcashAddress * @next Failure */ message ZcashDisplayAddress { - repeated uint32 address_n = 1; // ZIP-32 derivation path [32', 133', account'] - optional uint32 account = 2; // Account index (alternative to full path) + repeated uint32 address_n = 1; // ZIP-32 path [32', 133', account'] — required if account omitted + optional uint32 account = 2; // Account index — required if address_n omitted optional string address = 3; // Host-computed unified address ("u1...") - optional bytes ak = 4; // 32-byte ak for FVK verification - optional bytes nk = 5; // 32-byte nk for FVK verification - optional bytes rivk = 6; // 32-byte rivk for FVK verification + optional bytes ak = 4; // 32-byte ak for Orchard FVK verification + optional bytes nk = 5; // 32-byte nk for Orchard FVK verification + optional bytes rivk = 6; // 32-byte rivk for Orchard FVK verification } /** From 0e3dc97f3eabfdaeb68e7c08b0fc88452eba990a Mon Sep 17 00:00:00 2001 From: highlander Date: Tue, 28 Apr 2026 19:54:03 -0500 Subject: [PATCH 05/15] feat(tron): add SignMessage (TIP-191), VerifyMessage, SignTypedHash (TIP-712) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds proto definitions for TRON message-signing parity: - TronSignMessage / TronMessageSignature (1404/1405) — TIP-191 personal_sign - TronVerifyMessage (1406) — host-asserted signature verification - TronSignTypedHash / TronTypedDataSignature (1407/1408) — TIP-712 hash mode Mirrors the Ethereum personal_sign + EIP-712 hash-mode shape. Firmware implementation will reuse the secp256k1 + keccak256 primitives already present for Ethereum, swapping the message prefix to '\x19TRON Signed Message:\n' for TIP-191 and using '\x19\x01' for TIP-712. Reserves IDs 1404-1408 contiguous to existing TRON range (1400-1403). --- messages-tron.options | 14 ++++++++++ messages-tron.proto | 65 +++++++++++++++++++++++++++++++++++++++++++ messages.proto | 5 ++++ 3 files changed, 84 insertions(+) diff --git a/messages-tron.options b/messages-tron.options index c6437134..1e2ca71a 100644 --- a/messages-tron.options +++ b/messages-tron.options @@ -14,3 +14,17 @@ TronTriggerSmartContract.contract_address max_size:35 TronTriggerSmartContract.data max_size:512 TronSignTx.data max_size:256 TronSignedTx.serialized_tx max_size:1024 +TronSignMessage.address_n max_count:8 +TronSignMessage.coin_name max_size:21 +TronSignMessage.message max_size:1024 +TronMessageSignature.address max_size:35 +TronMessageSignature.signature max_size:65 +TronVerifyMessage.address max_size:35 +TronVerifyMessage.signature max_size:65 +TronVerifyMessage.message max_size:1024 +TronSignTypedHash.address_n max_count:8 +TronSignTypedHash.coin_name max_size:21 +TronSignTypedHash.domain_separator_hash max_size:32 +TronSignTypedHash.message_hash max_size:32 +TronTypedDataSignature.address max_size:35 +TronTypedDataSignature.signature max_size:65 diff --git a/messages-tron.proto b/messages-tron.proto index cb566450..f091c785 100644 --- a/messages-tron.proto +++ b/messages-tron.proto @@ -81,3 +81,68 @@ message TronSignedTx { optional bytes signature = 1; // ECDSA signature (65 bytes: r + s + recovery_id) optional bytes serialized_tx = 2; // Reconstructed raw_data bytes (for host verification) } + +////////////////////////////////////// +// TRON: Message signing (TIP-191) // +////////////////////////////////////// + +/** + * Request: Ask device to sign a message using TIP-191 personal_sign + * Hash: keccak256("\x19TRON Signed Message:\n" + len(message) + message) + * @next TronMessageSignature + * @next Failure + */ +message TronSignMessage { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional string coin_name = 2 [default='Tron']; + optional bytes message = 3; // Message bytes to sign + optional bool show_display = 4; // Show message on device display +} + +/** + * Response: Signed message + * @prev TronSignMessage + */ +message TronMessageSignature { + optional string address = 1; // Base58Check TRON address that signed + optional bytes signature = 2; // 65-byte signature (r + s + v) +} + +/** + * Request: Ask device to verify a TIP-191 message signature + * @next Success + * @next Failure + */ +message TronVerifyMessage { + optional string address = 1; // Base58Check TRON address claimed to have signed + optional bytes signature = 2; // 65-byte signature to verify + optional bytes message = 3; // Message that was signed +} + +////////////////////////////////////// +// TRON: Typed data signing (TIP-712)// +////////////////////////////////////// + +/** + * Request: Ask device to sign hash of typed data (TIP-712 hash mode) + * Domain separation: keccak256("\x19\x01" + domain_separator_hash + message_hash) + * Host pre-computes the EIP-712-style domainSeparator and message hashes. + * @start + * @next TronTypedDataSignature + * @next Failure + */ +message TronSignTypedHash { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional string coin_name = 2 [default='Tron']; + required bytes domain_separator_hash = 3; // 32-byte domainSeparator hash + optional bytes message_hash = 4; // 32-byte message hash (empty if domain-only) +} + +/** + * Response: Signed typed data + * @prev TronSignTypedHash + */ +message TronTypedDataSignature { + required string address = 1; // Base58Check TRON address that signed + required bytes signature = 2; // 65-byte signature (r + s + v) +} diff --git a/messages.proto b/messages.proto index e9f37e02..4dc4393a 100644 --- a/messages.proto +++ b/messages.proto @@ -224,6 +224,11 @@ enum MessageType { MessageType_TronAddress = 1401 [ (wire_out) = true ]; MessageType_TronSignTx = 1402 [ (wire_in) = true ]; MessageType_TronSignedTx = 1403 [ (wire_out) = true ]; + MessageType_TronSignMessage = 1404 [ (wire_in) = true ]; + MessageType_TronMessageSignature = 1405 [ (wire_out) = true ]; + MessageType_TronVerifyMessage = 1406 [ (wire_in) = true ]; + MessageType_TronSignTypedHash = 1407 [ (wire_in) = true ]; + MessageType_TronTypedDataSignature = 1408 [ (wire_out) = true ]; // TON MessageType_TonGetAddress = 1500 [ (wire_in) = true ]; From 20e646ad97b6aed005c8e54625076122f14c9d29 Mon Sep 17 00:00:00 2001 From: highlander Date: Tue, 28 Apr 2026 19:54:31 -0500 Subject: [PATCH 06/15] feat(ton): add SignMessage Ed25519 message-signing primitive MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds TonSignMessage / TonMessageSignature (1504/1505) — basic Ed25519 arbitrary-bytes signing, mirroring SolanaSignMessage's shape. This primitive lacks domain separation by design (raw Ed25519 over message bytes). Firmware should gate it behind the AdvancedMode policy — same fence used for SolanaSignMessage in fsm_msg_solana.h — until a TON Connect ton_proof envelope is added as a separate proto. Reserves IDs 1504-1505 contiguous to existing TON range (1500-1503). --- messages-ton.options | 5 +++++ messages-ton.proto | 28 ++++++++++++++++++++++++++++ messages.proto | 2 ++ 3 files changed, 35 insertions(+) diff --git a/messages-ton.options b/messages-ton.options index 3b046331..91bf283e 100644 --- a/messages-ton.options +++ b/messages-ton.options @@ -8,3 +8,8 @@ TonSignTx.memo max_size:121 TonAddress.address max_size:50 TonAddress.raw_address max_size:70 TonSignedTx.signature max_size:64 +TonSignMessage.address_n max_count:8 +TonSignMessage.coin_name max_size:21 +TonSignMessage.message max_size:1024 +TonMessageSignature.public_key max_size:32 +TonMessageSignature.signature max_size:64 diff --git a/messages-ton.proto b/messages-ton.proto index 6813fbd4..09e44eba 100644 --- a/messages-ton.proto +++ b/messages-ton.proto @@ -70,3 +70,31 @@ message TonSignTx { message TonSignedTx { optional bytes signature = 1; // Ed25519 signature (64 bytes) } + +////////////////////////////////////// +// TON: Message signing // +////////////////////////////////////// + +/** + * Request: Ask device to sign an arbitrary message with Ed25519 + * Note: lacks domain separation by default. Firmware policy may gate + * this behind AdvancedMode (matching the SolanaSignMessage pattern) + * until a TON Connect-style envelope (ton_proof) is implemented. + * @next TonMessageSignature + * @next Failure + */ +message TonSignMessage { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional string coin_name = 2 [default='Ton']; + optional bytes message = 3; // Message bytes to sign + optional bool show_display = 4; // Show message on device display +} + +/** + * Response: Ed25519 signature and public key for the signed message + * @prev TonSignMessage + */ +message TonMessageSignature { + optional bytes public_key = 1; // 32-byte Ed25519 public key + optional bytes signature = 2; // 64-byte Ed25519 signature +} diff --git a/messages.proto b/messages.proto index 4dc4393a..fc5ffdd0 100644 --- a/messages.proto +++ b/messages.proto @@ -235,6 +235,8 @@ enum MessageType { MessageType_TonAddress = 1501 [ (wire_out) = true ]; MessageType_TonSignTx = 1502 [ (wire_in) = true ]; MessageType_TonSignedTx = 1503 [ (wire_out) = true ]; + MessageType_TonSignMessage = 1504 [ (wire_in) = true ]; + MessageType_TonMessageSignature = 1505 [ (wire_out) = true ]; } //////////////////// From c0ef415fb77517d666200c2ffca381130d1b1733 Mon Sep 17 00:00:00 2001 From: highlander Date: Tue, 28 Apr 2026 19:55:01 -0500 Subject: [PATCH 07/15] feat(solana): add SignOffchainMessage with domain-separated envelope MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds SolanaSignOffchainMessage / SolanaOffchainMessageSignature (756/757) implementing the Solana off-chain message spec: '\xff' || 'solana offchain' || version || format || length || message The '\xff' lead byte is invalid as a Solana transaction prefix, providing the domain separation that plain SolanaSignMessage (754/755) lacks. With this primitive, firmware can drop the AdvancedMode policy gate currently required for SolanaSignMessage (fsm_msg_solana.h:461-472) for ASCII/UTF8 off-chain messages, since the envelope makes transaction-shaped attacks impossible. message_format values per spec: 0 = Restricted ASCII (max 1212 bytes) — display-renderable 1 = UTF-8 limited (max 1212 bytes) — display-renderable with care 2 = UTF-8 extended (max 65515) — blind-sign only Reserves IDs 756-757 contiguous to existing Solana range (750-755). Bumped message max_size to 1212 to match the spec ceiling for formats 0/1. --- messages-solana.options | 5 +++++ messages-solana.proto | 37 +++++++++++++++++++++++++++++++++++++ messages.proto | 2 ++ 3 files changed, 44 insertions(+) diff --git a/messages-solana.options b/messages-solana.options index 411233ab..ee812da1 100644 --- a/messages-solana.options +++ b/messages-solana.options @@ -13,3 +13,8 @@ SolanaSignMessage.coin_name max_size:21 SolanaSignMessage.message max_size:1024 SolanaMessageSignature.public_key max_size:32 SolanaMessageSignature.signature max_size:64 +SolanaSignOffchainMessage.address_n max_count:8 +SolanaSignOffchainMessage.coin_name max_size:21 +SolanaSignOffchainMessage.message max_size:1212 +SolanaOffchainMessageSignature.public_key max_size:32 +SolanaOffchainMessageSignature.signature max_size:64 diff --git a/messages-solana.proto b/messages-solana.proto index e0c341e7..f0ca4484 100644 --- a/messages-solana.proto +++ b/messages-solana.proto @@ -79,3 +79,40 @@ message SolanaMessageSignature { optional bytes public_key = 1; // 32-byte Ed25519 public key optional bytes signature = 2; // 64-byte Ed25519 signature } + +/** + * Request: Ask device to sign a Solana off-chain message with domain separation + * + * Per the Solana off-chain message spec, the device signs over the envelope: + * "\xff" || "solana offchain" || || + * || || + * + * The "\xff" lead byte is invalid as a Solana transaction prefix, providing + * domain separation that plain SolanaSignMessage lacks. Firmware constructs + * the envelope from the components below; host supplies version/format/message. + * + * Format values: + * 0 = Restricted ASCII (printable, max 1212 bytes) — renderable on display + * 1 = UTF-8 (max 1212 bytes) — renderable, may need policy gate + * 2 = UTF-8 (max 65515 bytes) — Ledger-only mode, blind-sign + * + * @next SolanaOffchainMessageSignature + * @next Failure + */ +message SolanaSignOffchainMessage { + repeated uint32 address_n = 1; // BIP-32/BIP-44 path to signing key + optional string coin_name = 2 [default = "Solana"]; + optional uint32 version = 3 [default = 0]; // Off-chain message spec version (0 = current) + optional uint32 message_format = 4; // 0=ASCII, 1=UTF8 limited, 2=UTF8 extended + optional bytes message = 5; // Raw message payload (firmware wraps with envelope) + optional bool show_display = 6; // Show message on device display +} + +/** + * Response: Ed25519 signature over the off-chain message envelope + * @prev SolanaSignOffchainMessage + */ +message SolanaOffchainMessageSignature { + optional bytes public_key = 1; // 32-byte Ed25519 public key + optional bytes signature = 2; // 64-byte Ed25519 signature over the envelope +} diff --git a/messages.proto b/messages.proto index fc5ffdd0..ca35898c 100644 --- a/messages.proto +++ b/messages.proto @@ -140,6 +140,8 @@ enum MessageType { MessageType_SolanaSignedTx = 753 [ (wire_out) = true ]; MessageType_SolanaSignMessage = 754 [ (wire_in) = true ]; MessageType_SolanaMessageSignature = 755 [ (wire_out) = true ]; + MessageType_SolanaSignOffchainMessage = 756 [ (wire_in) = true ]; + MessageType_SolanaOffchainMessageSignature = 757 [ (wire_out) = true ]; // Binance MessageType_BinanceGetAddress = 800 [ (wire_in) = true ]; From 872151217c295bad1ccf707af12376b6b60b5e57 Mon Sep 17 00:00:00 2001 From: highlander Date: Tue, 28 Apr 2026 20:55:57 -0500 Subject: [PATCH 08/15] feat(zcash): add seed_fingerprint binding to FVK / address / sign messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ZIP-32 §6.1 seed fingerprint: SeedFingerprint := BLAKE2b-256("Zcash_HD_Seed_FP", seed) A 32-byte stable identity of the device's seed. Adds optional bytes seed_fingerprint fields across the existing zcash messages so hosts and devices can bind FVKs, addresses, and signing sessions to a specific seed identity. Four new fields, all optional, fully backward compatible: ZcashOrchardFVK.seed_fingerprint (4) Returned alongside (ak, nk, rivk). Lets a host pin an FVK to this device's seed. ZcashAddress.seed_fingerprint (2) Returned alongside the confirmed UA after on-device verification. Lets a host record "this address is on this device's seed." ZcashSignPCZT.expected_seed_fingerprint (31) Sent by host. If present, device checks against its own fingerprint and rejects with Failure on mismatch before signing. Mirrors Keystone3's PCZT zip32_derivation seed_fingerprint check at the session level (one tx = one seed, no per-action duplication needed for our flow). ZcashDisplayAddress.expected_seed_fingerprint (7) Sent by host. Same rejection semantics as above before displaying. Matching nanopb max_size:32 entries added to messages-zcash.options. No existing fields modified. Devices and hosts that don't populate the new fields continue to work unchanged. --- messages-zcash.options | 4 ++++ messages-zcash.proto | 13 +++++++++++++ 2 files changed, 17 insertions(+) diff --git a/messages-zcash.options b/messages-zcash.options index a80f1ec3..c32611d3 100644 --- a/messages-zcash.options +++ b/messages-zcash.options @@ -5,6 +5,7 @@ ZcashSignPCZT.transparent_digest max_size:32 ZcashSignPCZT.sapling_digest max_size:32 ZcashSignPCZT.orchard_digest max_size:32 ZcashSignPCZT.orchard_anchor max_size:32 +ZcashSignPCZT.expected_seed_fingerprint max_size:32 ZcashPCZTAction.alpha max_size:32 ZcashPCZTAction.sighash max_size:32 @@ -26,6 +27,7 @@ ZcashGetOrchardFVK.address_n max_count:8 ZcashOrchardFVK.ak max_size:32 ZcashOrchardFVK.nk max_size:32 ZcashOrchardFVK.rivk max_size:32 +ZcashOrchardFVK.seed_fingerprint max_size:32 ZcashTransparentInput.sighash max_size:32 ZcashTransparentInput.address_n max_count:8 @@ -37,5 +39,7 @@ ZcashDisplayAddress.address max_size:128 ZcashDisplayAddress.ak max_size:32 ZcashDisplayAddress.nk max_size:32 ZcashDisplayAddress.rivk max_size:32 +ZcashDisplayAddress.expected_seed_fingerprint max_size:32 ZcashAddress.address max_size:128 +ZcashAddress.seed_fingerprint max_size:32 diff --git a/messages-zcash.proto b/messages-zcash.proto index 4eaf7dd2..0a00b927 100644 --- a/messages-zcash.proto +++ b/messages-zcash.proto @@ -40,6 +40,10 @@ message ZcashSignPCZT { optional bytes orchard_anchor = 14; // 32-byte orchard anchor // Phase 3: transparent shielding support optional uint32 n_transparent_inputs = 30; // 0 for shielded-only (default), >0 for hybrid shielding tx + // Seed identity binding (ZIP-32 §6.1) + optional bytes expected_seed_fingerprint = 31; // 32-byte BLAKE2b-256("Zcash_HD_Seed_FP", seed). + // If present, device verifies match against its own + // seed fingerprint and rejects with Failure on mismatch. } /** @@ -116,6 +120,9 @@ message ZcashOrchardFVK { optional bytes ak = 1; // 32-byte authorizing key (Pallas point) optional bytes nk = 2; // 32-byte nullifier deriving key optional bytes rivk = 3; // 32-byte commitment randomness key + optional bytes seed_fingerprint = 4; // 32-byte BLAKE2b-256("Zcash_HD_Seed_FP", seed) — ZIP-32 §6.1 + // Stable identity of the device's seed; lets a host pin an FVK + // to a specific seed across sessions. } /** @@ -182,6 +189,9 @@ message ZcashDisplayAddress { optional bytes ak = 4; // 32-byte ak for Orchard FVK verification optional bytes nk = 5; // 32-byte nk for Orchard FVK verification optional bytes rivk = 6; // 32-byte rivk for Orchard FVK verification + optional bytes expected_seed_fingerprint = 7; // 32-byte ZIP-32 §6.1 seed fingerprint. + // If present, device verifies match against its own + // seed fingerprint and rejects with Failure on mismatch. } /** @@ -191,4 +201,7 @@ message ZcashDisplayAddress { */ message ZcashAddress { optional string address = 1; // Confirmed unified address + optional bytes seed_fingerprint = 2; // 32-byte ZIP-32 §6.1 seed fingerprint of the attesting + // device. Returned alongside the confirmed address so a host + // can record that this UA is bound to this device's seed. } From ef80b30a823e18739b2354838be5d2a50b159fad Mon Sep 17 00:00:00 2001 From: highlander Date: Tue, 28 Apr 2026 21:54:42 -0500 Subject: [PATCH 09/15] fix(zcash): correct seed_fingerprint formula in proto comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Field comments documented the formula as BLAKE2b-256("Zcash_HD_Seed_FP", seed) but ZIP-32 §6.1 (and the actual conforming implementations in the upstream zip32 Rust crate, keystone3-firmware, and our own firmware) prepend a 1-byte length: BLAKE2b-256("Zcash_HD_Seed_FP", I2LEBSP_8(len(seed)) || seed) A host implementer following the proto comments would compute the wrong fingerprint and have the device reject every signing/display request with "seed fingerprint mismatch." Comment-only change. No wire-format impact. --- messages-zcash.proto | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/messages-zcash.proto b/messages-zcash.proto index 0a00b927..10c13a2a 100644 --- a/messages-zcash.proto +++ b/messages-zcash.proto @@ -41,7 +41,9 @@ message ZcashSignPCZT { // Phase 3: transparent shielding support optional uint32 n_transparent_inputs = 30; // 0 for shielded-only (default), >0 for hybrid shielding tx // Seed identity binding (ZIP-32 §6.1) - optional bytes expected_seed_fingerprint = 31; // 32-byte BLAKE2b-256("Zcash_HD_Seed_FP", seed). + optional bytes expected_seed_fingerprint = 31; // 32-byte ZIP-32 §6.1 seed fingerprint: + // BLAKE2b-256("Zcash_HD_Seed_FP", + // I2LEBSP_8(len(seed)) || seed) // If present, device verifies match against its own // seed fingerprint and rejects with Failure on mismatch. } @@ -120,7 +122,9 @@ message ZcashOrchardFVK { optional bytes ak = 1; // 32-byte authorizing key (Pallas point) optional bytes nk = 2; // 32-byte nullifier deriving key optional bytes rivk = 3; // 32-byte commitment randomness key - optional bytes seed_fingerprint = 4; // 32-byte BLAKE2b-256("Zcash_HD_Seed_FP", seed) — ZIP-32 §6.1 + optional bytes seed_fingerprint = 4; // 32-byte ZIP-32 §6.1 seed fingerprint: + // BLAKE2b-256("Zcash_HD_Seed_FP", + // I2LEBSP_8(len(seed)) || seed) // Stable identity of the device's seed; lets a host pin an FVK // to a specific seed across sessions. } From 870b8eaf5bcad0e62231bc0947207d6863c0553e Mon Sep 17 00:00:00 2001 From: highlander Date: Thu, 30 Apr 2026 17:12:49 -0500 Subject: [PATCH 10/15] feat(zcash): drop host-supplied UA from ZcashDisplayAddress MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove fields 3-6 (address, ak, nk, rivk) from ZcashDisplayAddress. Field numbers are reserved to prevent reuse. The on-device UA derivation (Sinsemilla + SWU hash-to-curve) shipped — FVK-match attestation against a host-built UA is strictly weaker than device-derived display and is no longer supported. What stays: address_n / account / expected_seed_fingerprint. What ZcashAddress returns: address (now device-derived) + seed_fingerprint. --- messages-zcash.options | 4 ---- messages-zcash.proto | 36 ++++++++++++++---------------------- 2 files changed, 14 insertions(+), 26 deletions(-) diff --git a/messages-zcash.options b/messages-zcash.options index 9e9f9992..31426964 100644 --- a/messages-zcash.options +++ b/messages-zcash.options @@ -35,10 +35,6 @@ ZcashTransparentInput.address_n max_count:8 ZcashTransparentSig.signature max_size:73 ZcashDisplayAddress.address_n max_count:8 -ZcashDisplayAddress.address max_size:256 -ZcashDisplayAddress.ak max_size:32 -ZcashDisplayAddress.nk max_size:32 -ZcashDisplayAddress.rivk max_size:32 ZcashDisplayAddress.expected_seed_fingerprint max_size:32 ZcashAddress.address max_size:256 diff --git a/messages-zcash.proto b/messages-zcash.proto index 10c13a2a..ac65c1c5 100644 --- a/messages-zcash.proto +++ b/messages-zcash.proto @@ -161,38 +161,30 @@ message ZcashTransparentSig { } /** - * Request: Display a Zcash unified address on the device screen. + * Request: Display the device-derived Orchard unified address on screen. * - * The host provides the unified address string and the FVK components - * (ak, nk, rivk) used to derive it. The device independently derives - * the FVK from the seed and verifies it matches the provided components - * before displaying the address with a QR code. + * The device derives the Orchard-only Unified Address (Sinsemilla + SWU + * hash-to-curve, default diversifier index 0) from its own seed at the + * requested account and shows it on the OLED with a QR code. What appears + * on screen is bound to this device — there is no host-supplied address + * to validate. * - * VERIFICATION SCOPE: The device only verifies that the Orchard FVK - * (ak, nk, rivk) in this request matches what it derives from the seed - * at the given account. A Unified Address may bundle receivers from - * multiple pools (transparent, Sapling, Orchard). The device CANNOT - * verify non-Orchard receivers — the guarantee is limited to: - * "This UA contains an Orchard receiver from this account." - * It does NOT guarantee that transparent or Sapling receivers (if - * present) are also controlled by this device. + * Either account or a complete address_n path (m/32'/133'/account', all + * hardened) is REQUIRED. The device rejects requests that omit both. * - * Full on-device UA derivation (Sinsemilla + SWU hash-to-curve) - * is planned for a future firmware release. - * - * Either account or a complete address_n path is REQUIRED. - * The device will reject requests that omit both. + * Fields 3–6 (host-supplied address, ak, nk, rivk) were removed when the + * device gained on-device UA derivation: FVK-match attestation against a + * host-built UA is strictly weaker than device-derived display and was + * dropped. Field numbers are reserved to prevent reuse. * * @next ZcashAddress * @next Failure */ message ZcashDisplayAddress { + reserved 3, 4, 5, 6; + reserved "address", "ak", "nk", "rivk"; repeated uint32 address_n = 1; // ZIP-32 path [32', 133', account'] — required if account omitted optional uint32 account = 2; // Account index — required if address_n omitted - optional string address = 3; // Host-computed unified address ("u1...") - optional bytes ak = 4; // 32-byte ak for Orchard FVK verification - optional bytes nk = 5; // 32-byte nk for Orchard FVK verification - optional bytes rivk = 6; // 32-byte rivk for Orchard FVK verification optional bytes expected_seed_fingerprint = 7; // 32-byte ZIP-32 §6.1 seed fingerprint. // If present, device verifies match against its own // seed fingerprint and rejects with Failure on mismatch. From 8f80bcdcd04e91ea80bb04d9c5f5328081938299 Mon Sep 17 00:00:00 2001 From: highlander Date: Fri, 15 May 2026 14:10:52 -0300 Subject: [PATCH 11/15] feat(ripple): add memo field to RippleSignTx for THORChain swap routing Add optional string memo field (field 7) to RippleSignTx protobuf message. This enables THORChain swap routing memos and other arbitrary memo data to be included in XRP transactions signed by the device. --- lib/messages-ripple_pb.d.ts | 179 +++++ lib/messages-ripple_pb.js | 1425 +++++++++++++++++++++++++++++++++++ messages-ripple.proto | 1 + 3 files changed, 1605 insertions(+) create mode 100644 lib/messages-ripple_pb.d.ts create mode 100644 lib/messages-ripple_pb.js diff --git a/lib/messages-ripple_pb.d.ts b/lib/messages-ripple_pb.d.ts new file mode 100644 index 00000000..3c47e1ca --- /dev/null +++ b/lib/messages-ripple_pb.d.ts @@ -0,0 +1,179 @@ +// package: +// file: messages-ripple.proto + +import * as jspb from "google-protobuf"; + +export class RippleGetAddress extends jspb.Message { + clearAddressNList(): void; + getAddressNList(): Array; + setAddressNList(value: Array): void; + addAddressN(value: number, index?: number): number; + + hasShowDisplay(): boolean; + clearShowDisplay(): void; + getShowDisplay(): boolean | undefined; + setShowDisplay(value: boolean): void; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): RippleGetAddress.AsObject; + static toObject(includeInstance: boolean, msg: RippleGetAddress): RippleGetAddress.AsObject; + static extensions: {[key: number]: jspb.ExtensionFieldInfo}; + static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; + static serializeBinaryToWriter(message: RippleGetAddress, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): RippleGetAddress; + static deserializeBinaryFromReader(message: RippleGetAddress, reader: jspb.BinaryReader): RippleGetAddress; +} + +export namespace RippleGetAddress { + export type AsObject = { + addressNList: Array, + showDisplay?: boolean, + } +} + +export class RippleAddress extends jspb.Message { + hasAddress(): boolean; + clearAddress(): void; + getAddress(): string | undefined; + setAddress(value: string): void; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): RippleAddress.AsObject; + static toObject(includeInstance: boolean, msg: RippleAddress): RippleAddress.AsObject; + static extensions: {[key: number]: jspb.ExtensionFieldInfo}; + static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; + static serializeBinaryToWriter(message: RippleAddress, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): RippleAddress; + static deserializeBinaryFromReader(message: RippleAddress, reader: jspb.BinaryReader): RippleAddress; +} + +export namespace RippleAddress { + export type AsObject = { + address?: string, + } +} + +export class RippleSignTx extends jspb.Message { + clearAddressNList(): void; + getAddressNList(): Array; + setAddressNList(value: Array): void; + addAddressN(value: number, index?: number): number; + + hasFee(): boolean; + clearFee(): void; + getFee(): number | undefined; + setFee(value: number): void; + + hasFlags(): boolean; + clearFlags(): void; + getFlags(): number | undefined; + setFlags(value: number): void; + + hasSequence(): boolean; + clearSequence(): void; + getSequence(): number | undefined; + setSequence(value: number): void; + + hasLastLedgerSequence(): boolean; + clearLastLedgerSequence(): void; + getLastLedgerSequence(): number | undefined; + setLastLedgerSequence(value: number): void; + + hasPayment(): boolean; + clearPayment(): void; + getPayment(): RipplePayment | undefined; + setPayment(value?: RipplePayment): void; + + hasMemo(): boolean; + clearMemo(): void; + getMemo(): string | undefined; + setMemo(value: string): void; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): RippleSignTx.AsObject; + static toObject(includeInstance: boolean, msg: RippleSignTx): RippleSignTx.AsObject; + static extensions: {[key: number]: jspb.ExtensionFieldInfo}; + static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; + static serializeBinaryToWriter(message: RippleSignTx, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): RippleSignTx; + static deserializeBinaryFromReader(message: RippleSignTx, reader: jspb.BinaryReader): RippleSignTx; +} + +export namespace RippleSignTx { + export type AsObject = { + addressNList: Array, + fee?: number, + flags?: number, + sequence?: number, + lastLedgerSequence?: number, + payment?: RipplePayment.AsObject, + memo?: string, + } +} + +export class RipplePayment extends jspb.Message { + hasAmount(): boolean; + clearAmount(): void; + getAmount(): number | undefined; + setAmount(value: number): void; + + hasDestination(): boolean; + clearDestination(): void; + getDestination(): string | undefined; + setDestination(value: string): void; + + hasDestinationTag(): boolean; + clearDestinationTag(): void; + getDestinationTag(): number | undefined; + setDestinationTag(value: number): void; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): RipplePayment.AsObject; + static toObject(includeInstance: boolean, msg: RipplePayment): RipplePayment.AsObject; + static extensions: {[key: number]: jspb.ExtensionFieldInfo}; + static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; + static serializeBinaryToWriter(message: RipplePayment, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): RipplePayment; + static deserializeBinaryFromReader(message: RipplePayment, reader: jspb.BinaryReader): RipplePayment; +} + +export namespace RipplePayment { + export type AsObject = { + amount?: number, + destination?: string, + destinationTag?: number, + } +} + +export class RippleSignedTx extends jspb.Message { + hasSignature(): boolean; + clearSignature(): void; + getSignature(): Uint8Array | string; + getSignature_asU8(): Uint8Array; + getSignature_asB64(): string; + setSignature(value: Uint8Array | string): void; + + hasSerializedTx(): boolean; + clearSerializedTx(): void; + getSerializedTx(): Uint8Array | string; + getSerializedTx_asU8(): Uint8Array; + getSerializedTx_asB64(): string; + setSerializedTx(value: Uint8Array | string): void; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): RippleSignedTx.AsObject; + static toObject(includeInstance: boolean, msg: RippleSignedTx): RippleSignedTx.AsObject; + static extensions: {[key: number]: jspb.ExtensionFieldInfo}; + static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; + static serializeBinaryToWriter(message: RippleSignedTx, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): RippleSignedTx; + static deserializeBinaryFromReader(message: RippleSignedTx, reader: jspb.BinaryReader): RippleSignedTx; +} + +export namespace RippleSignedTx { + export type AsObject = { + signature: Uint8Array | string, + serializedTx: Uint8Array | string, + } +} + diff --git a/lib/messages-ripple_pb.js b/lib/messages-ripple_pb.js new file mode 100644 index 00000000..296100ad --- /dev/null +++ b/lib/messages-ripple_pb.js @@ -0,0 +1,1425 @@ +// source: messages-ripple.proto +/** + * @fileoverview + * @enhanceable + * @suppress {missingRequire} reports error on implicit type usages. + * @suppress {messageConventions} JS Compiler reports an error if a variable or + * field starts with 'MSG_' and isn't a translatable message. + * @public + */ +// GENERATED CODE -- DO NOT EDIT! +/* eslint-disable */ +// @ts-nocheck + +var jspb = require('google-protobuf'); +var goog = jspb; +var global = (function() { + if (this) { return this; } + if (typeof window !== 'undefined') { return window; } + if (typeof global !== 'undefined') { return global; } + if (typeof self !== 'undefined') { return self; } + return Function('return this')(); +}.call(null)); + +goog.exportSymbol('proto.RippleAddress', null, global); +goog.exportSymbol('proto.RippleGetAddress', null, global); +goog.exportSymbol('proto.RipplePayment', null, global); +goog.exportSymbol('proto.RippleSignTx', null, global); +goog.exportSymbol('proto.RippleSignedTx', null, global); +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.RippleGetAddress = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, proto.RippleGetAddress.repeatedFields_, null); +}; +goog.inherits(proto.RippleGetAddress, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.RippleGetAddress.displayName = 'proto.RippleGetAddress'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.RippleAddress = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.RippleAddress, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.RippleAddress.displayName = 'proto.RippleAddress'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.RippleSignTx = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, proto.RippleSignTx.repeatedFields_, null); +}; +goog.inherits(proto.RippleSignTx, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.RippleSignTx.displayName = 'proto.RippleSignTx'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.RipplePayment = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.RipplePayment, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.RipplePayment.displayName = 'proto.RipplePayment'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.RippleSignedTx = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.RippleSignedTx, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.RippleSignedTx.displayName = 'proto.RippleSignedTx'; +} + +/** + * List of repeated fields within this message type. + * @private {!Array} + * @const + */ +proto.RippleGetAddress.repeatedFields_ = [1]; + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.RippleGetAddress.prototype.toObject = function(opt_includeInstance) { + return proto.RippleGetAddress.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.RippleGetAddress} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.RippleGetAddress.toObject = function(includeInstance, msg) { + var f, obj = { + addressNList: (f = jspb.Message.getRepeatedField(msg, 1)) == null ? undefined : f, + showDisplay: (f = jspb.Message.getBooleanField(msg, 2)) == null ? undefined : f + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.RippleGetAddress} + */ +proto.RippleGetAddress.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.RippleGetAddress; + return proto.RippleGetAddress.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.RippleGetAddress} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.RippleGetAddress} + */ +proto.RippleGetAddress.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var values = /** @type {!Array} */ (reader.isDelimited() ? reader.readPackedUint32() : [reader.readUint32()]); + for (var i = 0; i < values.length; i++) { + msg.addAddressN(values[i]); + } + break; + case 2: + var value = /** @type {boolean} */ (reader.readBool()); + msg.setShowDisplay(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.RippleGetAddress.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.RippleGetAddress.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.RippleGetAddress} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.RippleGetAddress.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getAddressNList(); + if (f.length > 0) { + writer.writeRepeatedUint32( + 1, + f + ); + } + f = /** @type {boolean} */ (jspb.Message.getField(message, 2)); + if (f != null) { + writer.writeBool( + 2, + f + ); + } +}; + + +/** + * repeated uint32 address_n = 1; + * @return {!Array} + */ +proto.RippleGetAddress.prototype.getAddressNList = function() { + return /** @type {!Array} */ (jspb.Message.getRepeatedField(this, 1)); +}; + + +/** + * @param {!Array} value + * @return {!proto.RippleGetAddress} returns this + */ +proto.RippleGetAddress.prototype.setAddressNList = function(value) { + return jspb.Message.setField(this, 1, value || []); +}; + + +/** + * @param {number} value + * @param {number=} opt_index + * @return {!proto.RippleGetAddress} returns this + */ +proto.RippleGetAddress.prototype.addAddressN = function(value, opt_index) { + return jspb.Message.addToRepeatedField(this, 1, value, opt_index); +}; + + +/** + * Clears the list making it empty but non-null. + * @return {!proto.RippleGetAddress} returns this + */ +proto.RippleGetAddress.prototype.clearAddressNList = function() { + return this.setAddressNList([]); +}; + + +/** + * optional bool show_display = 2; + * @return {boolean} + */ +proto.RippleGetAddress.prototype.getShowDisplay = function() { + return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 2, false)); +}; + + +/** + * @param {boolean} value + * @return {!proto.RippleGetAddress} returns this + */ +proto.RippleGetAddress.prototype.setShowDisplay = function(value) { + return jspb.Message.setField(this, 2, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.RippleGetAddress} returns this + */ +proto.RippleGetAddress.prototype.clearShowDisplay = function() { + return jspb.Message.setField(this, 2, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.RippleGetAddress.prototype.hasShowDisplay = function() { + return jspb.Message.getField(this, 2) != null; +}; + + + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.RippleAddress.prototype.toObject = function(opt_includeInstance) { + return proto.RippleAddress.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.RippleAddress} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.RippleAddress.toObject = function(includeInstance, msg) { + var f, obj = { + address: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.RippleAddress} + */ +proto.RippleAddress.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.RippleAddress; + return proto.RippleAddress.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.RippleAddress} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.RippleAddress} + */ +proto.RippleAddress.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {string} */ (reader.readString()); + msg.setAddress(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.RippleAddress.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.RippleAddress.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.RippleAddress} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.RippleAddress.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = /** @type {string} */ (jspb.Message.getField(message, 1)); + if (f != null) { + writer.writeString( + 1, + f + ); + } +}; + + +/** + * optional string address = 1; + * @return {string} + */ +proto.RippleAddress.prototype.getAddress = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); +}; + + +/** + * @param {string} value + * @return {!proto.RippleAddress} returns this + */ +proto.RippleAddress.prototype.setAddress = function(value) { + return jspb.Message.setField(this, 1, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.RippleAddress} returns this + */ +proto.RippleAddress.prototype.clearAddress = function() { + return jspb.Message.setField(this, 1, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.RippleAddress.prototype.hasAddress = function() { + return jspb.Message.getField(this, 1) != null; +}; + + + +/** + * List of repeated fields within this message type. + * @private {!Array} + * @const + */ +proto.RippleSignTx.repeatedFields_ = [1]; + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.RippleSignTx.prototype.toObject = function(opt_includeInstance) { + return proto.RippleSignTx.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.RippleSignTx} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.RippleSignTx.toObject = function(includeInstance, msg) { + var f, obj = { + addressNList: (f = jspb.Message.getRepeatedField(msg, 1)) == null ? undefined : f, + fee: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f, + flags: (f = jspb.Message.getField(msg, 3)) == null ? undefined : f, + sequence: (f = jspb.Message.getField(msg, 4)) == null ? undefined : f, + lastLedgerSequence: (f = jspb.Message.getField(msg, 5)) == null ? undefined : f, + payment: (f = msg.getPayment()) && proto.RipplePayment.toObject(includeInstance, f), + memo: (f = jspb.Message.getField(msg, 7)) == null ? undefined : f + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.RippleSignTx} + */ +proto.RippleSignTx.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.RippleSignTx; + return proto.RippleSignTx.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.RippleSignTx} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.RippleSignTx} + */ +proto.RippleSignTx.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var values = /** @type {!Array} */ (reader.isDelimited() ? reader.readPackedUint32() : [reader.readUint32()]); + for (var i = 0; i < values.length; i++) { + msg.addAddressN(values[i]); + } + break; + case 2: + var value = /** @type {number} */ (reader.readUint64()); + msg.setFee(value); + break; + case 3: + var value = /** @type {number} */ (reader.readUint32()); + msg.setFlags(value); + break; + case 4: + var value = /** @type {number} */ (reader.readUint32()); + msg.setSequence(value); + break; + case 5: + var value = /** @type {number} */ (reader.readUint32()); + msg.setLastLedgerSequence(value); + break; + case 6: + var value = new proto.RipplePayment; + reader.readMessage(value,proto.RipplePayment.deserializeBinaryFromReader); + msg.setPayment(value); + break; + case 7: + var value = /** @type {string} */ (reader.readString()); + msg.setMemo(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.RippleSignTx.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.RippleSignTx.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.RippleSignTx} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.RippleSignTx.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getAddressNList(); + if (f.length > 0) { + writer.writeRepeatedUint32( + 1, + f + ); + } + f = /** @type {number} */ (jspb.Message.getField(message, 2)); + if (f != null) { + writer.writeUint64( + 2, + f + ); + } + f = /** @type {number} */ (jspb.Message.getField(message, 3)); + if (f != null) { + writer.writeUint32( + 3, + f + ); + } + f = /** @type {number} */ (jspb.Message.getField(message, 4)); + if (f != null) { + writer.writeUint32( + 4, + f + ); + } + f = /** @type {number} */ (jspb.Message.getField(message, 5)); + if (f != null) { + writer.writeUint32( + 5, + f + ); + } + f = message.getPayment(); + if (f != null) { + writer.writeMessage( + 6, + f, + proto.RipplePayment.serializeBinaryToWriter + ); + } + f = /** @type {string} */ (jspb.Message.getField(message, 7)); + if (f != null) { + writer.writeString( + 7, + f + ); + } +}; + + +/** + * repeated uint32 address_n = 1; + * @return {!Array} + */ +proto.RippleSignTx.prototype.getAddressNList = function() { + return /** @type {!Array} */ (jspb.Message.getRepeatedField(this, 1)); +}; + + +/** + * @param {!Array} value + * @return {!proto.RippleSignTx} returns this + */ +proto.RippleSignTx.prototype.setAddressNList = function(value) { + return jspb.Message.setField(this, 1, value || []); +}; + + +/** + * @param {number} value + * @param {number=} opt_index + * @return {!proto.RippleSignTx} returns this + */ +proto.RippleSignTx.prototype.addAddressN = function(value, opt_index) { + return jspb.Message.addToRepeatedField(this, 1, value, opt_index); +}; + + +/** + * Clears the list making it empty but non-null. + * @return {!proto.RippleSignTx} returns this + */ +proto.RippleSignTx.prototype.clearAddressNList = function() { + return this.setAddressNList([]); +}; + + +/** + * optional uint64 fee = 2; + * @return {number} + */ +proto.RippleSignTx.prototype.getFee = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.RippleSignTx} returns this + */ +proto.RippleSignTx.prototype.setFee = function(value) { + return jspb.Message.setField(this, 2, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.RippleSignTx} returns this + */ +proto.RippleSignTx.prototype.clearFee = function() { + return jspb.Message.setField(this, 2, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.RippleSignTx.prototype.hasFee = function() { + return jspb.Message.getField(this, 2) != null; +}; + + +/** + * optional uint32 flags = 3; + * @return {number} + */ +proto.RippleSignTx.prototype.getFlags = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.RippleSignTx} returns this + */ +proto.RippleSignTx.prototype.setFlags = function(value) { + return jspb.Message.setField(this, 3, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.RippleSignTx} returns this + */ +proto.RippleSignTx.prototype.clearFlags = function() { + return jspb.Message.setField(this, 3, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.RippleSignTx.prototype.hasFlags = function() { + return jspb.Message.getField(this, 3) != null; +}; + + +/** + * optional uint32 sequence = 4; + * @return {number} + */ +proto.RippleSignTx.prototype.getSequence = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 4, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.RippleSignTx} returns this + */ +proto.RippleSignTx.prototype.setSequence = function(value) { + return jspb.Message.setField(this, 4, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.RippleSignTx} returns this + */ +proto.RippleSignTx.prototype.clearSequence = function() { + return jspb.Message.setField(this, 4, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.RippleSignTx.prototype.hasSequence = function() { + return jspb.Message.getField(this, 4) != null; +}; + + +/** + * optional uint32 last_ledger_sequence = 5; + * @return {number} + */ +proto.RippleSignTx.prototype.getLastLedgerSequence = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 5, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.RippleSignTx} returns this + */ +proto.RippleSignTx.prototype.setLastLedgerSequence = function(value) { + return jspb.Message.setField(this, 5, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.RippleSignTx} returns this + */ +proto.RippleSignTx.prototype.clearLastLedgerSequence = function() { + return jspb.Message.setField(this, 5, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.RippleSignTx.prototype.hasLastLedgerSequence = function() { + return jspb.Message.getField(this, 5) != null; +}; + + +/** + * optional RipplePayment payment = 6; + * @return {?proto.RipplePayment} + */ +proto.RippleSignTx.prototype.getPayment = function() { + return /** @type{?proto.RipplePayment} */ ( + jspb.Message.getWrapperField(this, proto.RipplePayment, 6)); +}; + + +/** + * @param {?proto.RipplePayment|undefined} value + * @return {!proto.RippleSignTx} returns this +*/ +proto.RippleSignTx.prototype.setPayment = function(value) { + return jspb.Message.setWrapperField(this, 6, value); +}; + + +/** + * Clears the message field making it undefined. + * @return {!proto.RippleSignTx} returns this + */ +proto.RippleSignTx.prototype.clearPayment = function() { + return this.setPayment(undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.RippleSignTx.prototype.hasPayment = function() { + return jspb.Message.getField(this, 6) != null; +}; + + +/** + * optional string memo = 7; + * @return {string} + */ +proto.RippleSignTx.prototype.getMemo = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 7, "")); +}; + + +/** + * @param {string} value + * @return {!proto.RippleSignTx} returns this + */ +proto.RippleSignTx.prototype.setMemo = function(value) { + return jspb.Message.setField(this, 7, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.RippleSignTx} returns this + */ +proto.RippleSignTx.prototype.clearMemo = function() { + return jspb.Message.setField(this, 7, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.RippleSignTx.prototype.hasMemo = function() { + return jspb.Message.getField(this, 7) != null; +}; + + + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.RipplePayment.prototype.toObject = function(opt_includeInstance) { + return proto.RipplePayment.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.RipplePayment} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.RipplePayment.toObject = function(includeInstance, msg) { + var f, obj = { + amount: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f, + destination: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f, + destinationTag: (f = jspb.Message.getField(msg, 3)) == null ? undefined : f + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.RipplePayment} + */ +proto.RipplePayment.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.RipplePayment; + return proto.RipplePayment.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.RipplePayment} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.RipplePayment} + */ +proto.RipplePayment.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {number} */ (reader.readUint64()); + msg.setAmount(value); + break; + case 2: + var value = /** @type {string} */ (reader.readString()); + msg.setDestination(value); + break; + case 3: + var value = /** @type {number} */ (reader.readUint32()); + msg.setDestinationTag(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.RipplePayment.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.RipplePayment.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.RipplePayment} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.RipplePayment.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = /** @type {number} */ (jspb.Message.getField(message, 1)); + if (f != null) { + writer.writeUint64( + 1, + f + ); + } + f = /** @type {string} */ (jspb.Message.getField(message, 2)); + if (f != null) { + writer.writeString( + 2, + f + ); + } + f = /** @type {number} */ (jspb.Message.getField(message, 3)); + if (f != null) { + writer.writeUint32( + 3, + f + ); + } +}; + + +/** + * optional uint64 amount = 1; + * @return {number} + */ +proto.RipplePayment.prototype.getAmount = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.RipplePayment} returns this + */ +proto.RipplePayment.prototype.setAmount = function(value) { + return jspb.Message.setField(this, 1, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.RipplePayment} returns this + */ +proto.RipplePayment.prototype.clearAmount = function() { + return jspb.Message.setField(this, 1, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.RipplePayment.prototype.hasAmount = function() { + return jspb.Message.getField(this, 1) != null; +}; + + +/** + * optional string destination = 2; + * @return {string} + */ +proto.RipplePayment.prototype.getDestination = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, "")); +}; + + +/** + * @param {string} value + * @return {!proto.RipplePayment} returns this + */ +proto.RipplePayment.prototype.setDestination = function(value) { + return jspb.Message.setField(this, 2, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.RipplePayment} returns this + */ +proto.RipplePayment.prototype.clearDestination = function() { + return jspb.Message.setField(this, 2, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.RipplePayment.prototype.hasDestination = function() { + return jspb.Message.getField(this, 2) != null; +}; + + +/** + * optional uint32 destination_tag = 3; + * @return {number} + */ +proto.RipplePayment.prototype.getDestinationTag = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.RipplePayment} returns this + */ +proto.RipplePayment.prototype.setDestinationTag = function(value) { + return jspb.Message.setField(this, 3, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.RipplePayment} returns this + */ +proto.RipplePayment.prototype.clearDestinationTag = function() { + return jspb.Message.setField(this, 3, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.RipplePayment.prototype.hasDestinationTag = function() { + return jspb.Message.getField(this, 3) != null; +}; + + + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.RippleSignedTx.prototype.toObject = function(opt_includeInstance) { + return proto.RippleSignedTx.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.RippleSignedTx} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.RippleSignedTx.toObject = function(includeInstance, msg) { + var f, obj = { + signature: msg.getSignature_asB64(), + serializedTx: msg.getSerializedTx_asB64() + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.RippleSignedTx} + */ +proto.RippleSignedTx.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.RippleSignedTx; + return proto.RippleSignedTx.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.RippleSignedTx} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.RippleSignedTx} + */ +proto.RippleSignedTx.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {!Uint8Array} */ (reader.readBytes()); + msg.setSignature(value); + break; + case 2: + var value = /** @type {!Uint8Array} */ (reader.readBytes()); + msg.setSerializedTx(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.RippleSignedTx.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.RippleSignedTx.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.RippleSignedTx} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.RippleSignedTx.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = /** @type {!(string|Uint8Array)} */ (jspb.Message.getField(message, 1)); + if (f != null) { + writer.writeBytes( + 1, + f + ); + } + f = /** @type {!(string|Uint8Array)} */ (jspb.Message.getField(message, 2)); + if (f != null) { + writer.writeBytes( + 2, + f + ); + } +}; + + +/** + * optional bytes signature = 1; + * @return {!(string|Uint8Array)} + */ +proto.RippleSignedTx.prototype.getSignature = function() { + return /** @type {!(string|Uint8Array)} */ (jspb.Message.getFieldWithDefault(this, 1, "")); +}; + + +/** + * optional bytes signature = 1; + * This is a type-conversion wrapper around `getSignature()` + * @return {string} + */ +proto.RippleSignedTx.prototype.getSignature_asB64 = function() { + return /** @type {string} */ (jspb.Message.bytesAsB64( + this.getSignature())); +}; + + +/** + * optional bytes signature = 1; + * Note that Uint8Array is not supported on all browsers. + * @see http://caniuse.com/Uint8Array + * This is a type-conversion wrapper around `getSignature()` + * @return {!Uint8Array} + */ +proto.RippleSignedTx.prototype.getSignature_asU8 = function() { + return /** @type {!Uint8Array} */ (jspb.Message.bytesAsU8( + this.getSignature())); +}; + + +/** + * @param {!(string|Uint8Array)} value + * @return {!proto.RippleSignedTx} returns this + */ +proto.RippleSignedTx.prototype.setSignature = function(value) { + return jspb.Message.setField(this, 1, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.RippleSignedTx} returns this + */ +proto.RippleSignedTx.prototype.clearSignature = function() { + return jspb.Message.setField(this, 1, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.RippleSignedTx.prototype.hasSignature = function() { + return jspb.Message.getField(this, 1) != null; +}; + + +/** + * optional bytes serialized_tx = 2; + * @return {!(string|Uint8Array)} + */ +proto.RippleSignedTx.prototype.getSerializedTx = function() { + return /** @type {!(string|Uint8Array)} */ (jspb.Message.getFieldWithDefault(this, 2, "")); +}; + + +/** + * optional bytes serialized_tx = 2; + * This is a type-conversion wrapper around `getSerializedTx()` + * @return {string} + */ +proto.RippleSignedTx.prototype.getSerializedTx_asB64 = function() { + return /** @type {string} */ (jspb.Message.bytesAsB64( + this.getSerializedTx())); +}; + + +/** + * optional bytes serialized_tx = 2; + * Note that Uint8Array is not supported on all browsers. + * @see http://caniuse.com/Uint8Array + * This is a type-conversion wrapper around `getSerializedTx()` + * @return {!Uint8Array} + */ +proto.RippleSignedTx.prototype.getSerializedTx_asU8 = function() { + return /** @type {!Uint8Array} */ (jspb.Message.bytesAsU8( + this.getSerializedTx())); +}; + + +/** + * @param {!(string|Uint8Array)} value + * @return {!proto.RippleSignedTx} returns this + */ +proto.RippleSignedTx.prototype.setSerializedTx = function(value) { + return jspb.Message.setField(this, 2, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.RippleSignedTx} returns this + */ +proto.RippleSignedTx.prototype.clearSerializedTx = function() { + return jspb.Message.setField(this, 2, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.RippleSignedTx.prototype.hasSerializedTx = function() { + return jspb.Message.getField(this, 2) != null; +}; + + +goog.object.extend(exports, proto); diff --git a/messages-ripple.proto b/messages-ripple.proto index 0fc012d2..bf526ef7 100644 --- a/messages-ripple.proto +++ b/messages-ripple.proto @@ -34,6 +34,7 @@ message RippleSignTx { optional uint32 sequence = 4; // transaction sequence number optional uint32 last_ledger_sequence = 5; // see https://developers.ripple.com/reliable-transaction-submission.html#lastledgersequence optional RipplePayment payment = 6; // Payment transaction type + optional string memo = 7; // transaction memo (e.g. THORChain swap routing memo) } /** From f2b32d8a26aa311e19aebdde5659a10b23cf0765 Mon Sep 17 00:00:00 2001 From: highlander Date: Sat, 16 May 2026 18:00:52 -0300 Subject: [PATCH 12/15] feat(hive): add Hive blockchain message definitions Adds messages-hive.proto with HiveGetPublicKey, HivePublicKey, HiveSignTx, and HiveSignedTx. Assigns message type IDs 1600-1603 in messages.proto. Co-Authored-By: Claude Sonnet 4.6 --- messages-hive.proto | 53 +++++++++++++++++++++++++++++++++++++++++++++ messages.proto | 6 +++++ 2 files changed, 59 insertions(+) create mode 100644 messages-hive.proto diff --git a/messages-hive.proto b/messages-hive.proto new file mode 100644 index 00000000..b4d4e545 --- /dev/null +++ b/messages-hive.proto @@ -0,0 +1,53 @@ +syntax = "proto2"; + +option java_package = "com.shapeshift.keepkey.lib.protobuf"; +option java_outer_classname = "KeepKeyMessageHive"; + +/** + * Request: Ask device for Hive public key at given BIP-32 path + * @start + * @next HivePublicKey + * @next Failure + */ +message HiveGetPublicKey { + repeated uint32 address_n = 1; // BIP-32 path, e.g. m/44'/1275'/0'/0/0 + optional bool show_display = 2; // show on device before returning +} + +/** + * Response: Hive public key + * @end + */ +message HivePublicKey { + optional string public_key = 1; // STM-prefixed base58 public key + optional bytes raw_public_key = 2; // 33-byte compressed public key +} + +/** + * Request: Sign a Hive transfer transaction + * @start + * @next HiveSignedTx + * @next Failure + */ +message HiveSignTx { + repeated uint32 address_n = 1; // BIP-32 path + optional bytes chain_id = 2; // 32-byte chain id (mainnet = beeab0de...) + optional uint32 ref_block_num = 3; // reference block number (uint16) + optional uint32 ref_block_prefix = 4; // reference block prefix (uint32) + optional uint32 expiration = 5; // expiration Unix timestamp (uint32) + optional string from = 6; // sender account name + optional string to = 7; // recipient account name + optional uint64 amount = 8; // amount in smallest unit (e.g. milliHIVE = 1/1000 HIVE) + optional uint32 decimals = 9; // token decimal places (3 for HIVE/HBD) + optional string asset_symbol = 10; // "HIVE" or "HBD" + optional string memo = 11; // optional memo +} + +/** + * Response: Signature for the Hive transaction + * @end + */ +message HiveSignedTx { + optional bytes signature = 1; // 65-byte secp256k1 signature (recoverable) + optional bytes serialized_tx = 2; // full serialized transaction bytes +} diff --git a/messages.proto b/messages.proto index ca35898c..3166ed4e 100644 --- a/messages.proto +++ b/messages.proto @@ -239,6 +239,12 @@ enum MessageType { MessageType_TonSignedTx = 1503 [ (wire_out) = true ]; MessageType_TonSignMessage = 1504 [ (wire_in) = true ]; MessageType_TonMessageSignature = 1505 [ (wire_out) = true ]; + + // Hive + MessageType_HiveGetPublicKey = 1600 [ (wire_in) = true ]; + MessageType_HivePublicKey = 1601 [ (wire_out) = true ]; + MessageType_HiveSignTx = 1602 [ (wire_in) = true ]; + MessageType_HiveSignedTx = 1603 [ (wire_out) = true ]; } //////////////////// From 922b6946e5b50e3662e787811d96c5d238786289 Mon Sep 17 00:00:00 2001 From: highlander Date: Wed, 20 May 2026 17:05:15 -0300 Subject: [PATCH 13/15] feat(zcash): add clear-signing protocol fields --- messages-zcash.options | 8 ++++- messages-zcash.proto | 70 +++++++++++++++++++++++++++++++++--------- messages.proto | 4 ++- 3 files changed, 65 insertions(+), 17 deletions(-) diff --git a/messages-zcash.options b/messages-zcash.options index 31426964..2ebcb224 100644 --- a/messages-zcash.options +++ b/messages-zcash.options @@ -18,6 +18,8 @@ ZcashPCZTAction.enc_memo max_size:512 ZcashPCZTAction.enc_noncompact max_size:612 ZcashPCZTAction.rk max_size:32 ZcashPCZTAction.out_ciphertext max_size:80 +ZcashPCZTAction.recipient max_size:43 +ZcashPCZTAction.rseed max_size:32 ZcashSignedPCZT.signatures max_count:64 max_size:64 ZcashSignedPCZT.txid max_size:32 @@ -29,10 +31,14 @@ ZcashOrchardFVK.nk max_size:32 ZcashOrchardFVK.rivk max_size:32 ZcashOrchardFVK.seed_fingerprint max_size:32 +ZcashTransparentOutput.script_pubkey max_size:128 + ZcashTransparentInput.sighash max_size:32 ZcashTransparentInput.address_n max_count:8 +ZcashTransparentInput.prevout_txid max_size:32 +ZcashTransparentInput.script_pubkey max_size:128 -ZcashTransparentSig.signature max_size:73 +ZcashTransparentSigned.signatures max_count:8 max_size:73 ZcashDisplayAddress.address_n max_count:8 ZcashDisplayAddress.expected_seed_fingerprint max_size:32 diff --git a/messages-zcash.proto b/messages-zcash.proto index ac65c1c5..c9659dd3 100644 --- a/messages-zcash.proto +++ b/messages-zcash.proto @@ -18,6 +18,7 @@ option java_outer_classname = "KeepKeyMessageZcash"; * The device derives spend authorization keys, computes the sighash, * and returns RedPallas signatures for each Orchard action. * + * @next ZcashTransparentAck * @next ZcashPCZTActionAck * @next Failure */ @@ -32,13 +33,19 @@ message ZcashSignPCZT { // Phase 2a: sub-digests for on-device sighash computation optional bytes header_digest = 8; // 32-byte pre-computed header digest optional bytes transparent_digest = 9; // 32-byte transparent digest (or empty) - optional bytes sapling_digest = 10; // 32-byte sapling digest (or empty) + optional bytes sapling_digest = 10; // Reserved for future Sapling support; currently rejected optional bytes orchard_digest = 11; // 32-byte orchard digest // Phase 2b: bundle metadata for orchard digest verification optional uint32 orchard_flags = 12; // Orchard bundle flags byte optional int64 orchard_value_balance = 13; // Orchard value balance (LE i64) optional bytes orchard_anchor = 14; // 32-byte orchard anchor + // Phase 4: plaintext header fields for on-device header digest verification + optional uint32 tx_version = 15; // Transaction version (without overwinter bit) + optional uint32 version_group_id = 16; // Version group ID + optional uint32 lock_time = 17; // Transaction lock time + optional uint32 expiry_height = 18; // Transaction expiry height // Phase 3: transparent shielding support + optional uint32 n_transparent_outputs = 29; // 0 for shielded-only (default) optional uint32 n_transparent_inputs = 30; // 0 for shielded-only (default), >0 for hybrid shielding tx // Seed identity binding (ZIP-32 §6.1) optional bytes expected_seed_fingerprint = 31; // 32-byte ZIP-32 §6.1 seed fingerprint: @@ -72,6 +79,11 @@ message ZcashPCZTAction { optional bytes enc_noncompact = 12; // Remaining encrypted note bytes optional bytes rk = 13; // 32-byte randomized verification key optional bytes out_ciphertext = 14; // 80-byte output ciphertext + // Phase 4: plaintext Orchard output metadata for trusted display. + // Firmware recomputes cmx from recipient/value/rseed and nullifier before + // displaying the receiver/value and before emitting any signature. + optional bytes recipient = 15; // 43-byte Orchard receiver: d || pk_d + optional bytes rseed = 16; // 32-byte output note rseed } /** @@ -129,35 +141,63 @@ message ZcashOrchardFVK { // to a specific seed across sessions. } +/** + * Request: Transparent output data for hybrid transactions. + * Sent before transparent inputs so the device can review standard + * transparent recipients before any signature is emitted. + * + * @next ZcashTransparentAck + * @next ZcashPCZTActionAck + * @next Failure + */ +message ZcashTransparentOutput { + required uint32 index = 1; // Output index within the transaction + optional uint64 amount = 2; // Output value in zatoshis + optional bytes script_pubkey = 3; // Standard P2PKH/P2SH scriptPubKey +} + /** * Request: Transparent input data for hybrid shielding transactions. - * Sent one per transparent input during the transparent signing phase. - * The device ECDSA-signs the per-input sighash with the secp256k1 key - * at the provided BIP44 path. + * Sent after all transparent outputs have been streamed. * - * Flow: after ZcashSignPCZT with n_transparent_inputs > 0, the device - * responds with ZcashPCZTActionAck. For each transparent input, the host - * sends ZcashTransparentInput and receives ZcashTransparentSig. After - * all transparent inputs, the device transitions to the Orchard phase. + * The device stores every input first because ZIP-244 per-input transparent + * sighashes commit to all transparent prevouts, values, scripts, sequences, + * and outputs. Host-provided sighash is legacy and rejected when present. * - * @next ZcashTransparentSig + * @next ZcashTransparentAck + * @next ZcashTransparentSigned * @next Failure */ message ZcashTransparentInput { required uint32 index = 1; // Input index within the transaction - required bytes sighash = 2; // 32-byte per-input sighash (host-computed, ZIP-244) + optional bytes sighash = 2; // Legacy host-computed sighash; rejected when present repeated uint32 address_n = 3; // BIP44 path [44', 133', 0', 0, 0] - optional uint64 amount = 4; // Input value in zatoshis (for display verification) + optional uint64 amount = 4; // Input value in zatoshis + optional bytes prevout_txid = 5; // Previous transaction ID + optional uint32 prevout_index = 6; // Previous output index + optional uint32 sequence = 7; // Input sequence + optional bytes script_pubkey = 8; // Previous output scriptPubKey +} + +/** + * Response: Acknowledgment requesting the next transparent item. + * + * @prev ZcashSignPCZT + * @prev ZcashTransparentOutput + * @prev ZcashTransparentInput + */ +message ZcashTransparentAck { + optional uint32 next_output_index = 1; // Next transparent output index + optional uint32 next_input_index = 2; // Next transparent input index } /** - * Response: ECDSA signature for a transparent input. + * Response: ECDSA signatures for transparent inputs. * * @prev ZcashTransparentInput */ -message ZcashTransparentSig { - required bytes signature = 1; // DER ECDSA signature (72-73 bytes) - optional uint32 next_index = 2; // Next transparent input index, or 0xFF = done +message ZcashTransparentSigned { + repeated bytes signatures = 1; // DER ECDSA signatures, one per transparent input } /** diff --git a/messages.proto b/messages.proto index 3166ed4e..28dbebf7 100644 --- a/messages.proto +++ b/messages.proto @@ -217,9 +217,11 @@ enum MessageType { MessageType_ZcashGetOrchardFVK = 1304 [ (wire_in) = true ]; MessageType_ZcashOrchardFVK = 1305 [ (wire_out) = true ]; MessageType_ZcashTransparentInput = 1306 [ (wire_in) = true ]; - MessageType_ZcashTransparentSig = 1307 [ (wire_out) = true ]; + MessageType_ZcashTransparentSigned = 1307 [ (wire_out) = true ]; MessageType_ZcashDisplayAddress = 1308 [ (wire_in) = true ]; MessageType_ZcashAddress = 1309 [ (wire_out) = true ]; + MessageType_ZcashTransparentOutput = 1310 [ (wire_in) = true ]; + MessageType_ZcashTransparentAck = 1311 [ (wire_out) = true ]; // TRON MessageType_TronGetAddress = 1400 [ (wire_in) = true ]; From c1dea4449be9fd5d5dfd66f4bd2f852d4b394c84 Mon Sep 17 00:00:00 2001 From: highlander Date: Thu, 21 May 2026 13:59:52 -0300 Subject: [PATCH 14/15] feat(thorchain): add denom field to ThorchainMsgSend (field 11) --- messages-thorchain.proto | 1 + 1 file changed, 1 insertion(+) diff --git a/messages-thorchain.proto b/messages-thorchain.proto index acde357a..00183623 100644 --- a/messages-thorchain.proto +++ b/messages-thorchain.proto @@ -60,6 +60,7 @@ message ThorchainMsgSend { optional uint64 amount = 8 [jstype = JS_STRING]; optional OutputAddressType address_type = 9; reserved 10; + optional string denom = 11; // asset denom, e.g. "rune" or IBC denom } message ThorchainMsgDeposit { From 2b25cf7a0ab4829ab8e7b741074dd794a06b2f58 Mon Sep 17 00:00:00 2001 From: Highlander Date: Sun, 24 May 2026 13:49:05 -0300 Subject: [PATCH 15/15] feat(hive): add Hive blockchain protobuf definitions (#31) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * release: device-protocol 7.14.1 * feat(tron): add SignMessage (TIP-191), VerifyMessage, SignTypedHash (TIP-712) Adds proto definitions for TRON message-signing parity: - TronSignMessage / TronMessageSignature (1404/1405) — TIP-191 personal_sign - TronVerifyMessage (1406) — host-asserted signature verification - TronSignTypedHash / TronTypedDataSignature (1407/1408) — TIP-712 hash mode Mirrors the Ethereum personal_sign + EIP-712 hash-mode shape. Firmware implementation will reuse the secp256k1 + keccak256 primitives already present for Ethereum, swapping the message prefix to '\x19TRON Signed Message:\n' for TIP-191 and using '\x19\x01' for TIP-712. Reserves IDs 1404-1408 contiguous to existing TRON range (1400-1403). * feat(ton): add SignMessage Ed25519 message-signing primitive Adds TonSignMessage / TonMessageSignature (1504/1505) — basic Ed25519 arbitrary-bytes signing, mirroring SolanaSignMessage's shape. This primitive lacks domain separation by design (raw Ed25519 over message bytes). Firmware should gate it behind the AdvancedMode policy — same fence used for SolanaSignMessage in fsm_msg_solana.h — until a TON Connect ton_proof envelope is added as a separate proto. Reserves IDs 1504-1505 contiguous to existing TON range (1500-1503). * feat(solana): add SignOffchainMessage with domain-separated envelope Adds SolanaSignOffchainMessage / SolanaOffchainMessageSignature (756/757) implementing the Solana off-chain message spec: '\xff' || 'solana offchain' || version || format || length || message The '\xff' lead byte is invalid as a Solana transaction prefix, providing the domain separation that plain SolanaSignMessage (754/755) lacks. With this primitive, firmware can drop the AdvancedMode policy gate currently required for SolanaSignMessage (fsm_msg_solana.h:461-472) for ASCII/UTF8 off-chain messages, since the envelope makes transaction-shaped attacks impossible. message_format values per spec: 0 = Restricted ASCII (max 1212 bytes) — display-renderable 1 = UTF-8 limited (max 1212 bytes) — display-renderable with care 2 = UTF-8 extended (max 65515) — blind-sign only Reserves IDs 756-757 contiguous to existing Solana range (750-755). Bumped message max_size to 1212 to match the spec ceiling for formats 0/1. * feat(zcash): drop host-supplied UA from ZcashDisplayAddress Remove fields 3-6 (address, ak, nk, rivk) from ZcashDisplayAddress. Field numbers are reserved to prevent reuse. The on-device UA derivation (Sinsemilla + SWU hash-to-curve) shipped — FVK-match attestation against a host-built UA is strictly weaker than device-derived display and is no longer supported. What stays: address_n / account / expected_seed_fingerprint. What ZcashAddress returns: address (now device-derived) + seed_fingerprint. * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * docs: update SolanaSignOffchainMessage to reflect 1212 byte limit and drop format 2 Agent-Logs-Url: https://github.com/keepkey/device-protocol/sessions/880cd954-b4b2-4f87-af05-8d715e1e0dc4 Co-authored-by: pastaghost <62026038+pastaghost@users.noreply.github.com> * feat(hive): add Hive blockchain message definitions Adds messages-hive.proto with HiveGetPublicKey, HivePublicKey, HiveSignTx, and HiveSignedTx. Assigns message type IDs 1600-1603 in messages.proto. Co-Authored-By: Claude Sonnet 4.6 * feat(hive): add messages-hive.proto to build, drop broken build:json step build:json used pbjs v0.0.5 which cannot parse proto3 reserved fields (present in zcash, cosmos, ethereum, etc). proto.json is unused by the vault — only messages_pb.js is imported. Build now runs build:js + build:postprocess only. * feat(hive): add HiveGetPublicKeys, HiveSignAccountCreate, HiveSignAccountUpdate + SLIP-0048 paths --------- Co-authored-by: pastaghost <62026038+pastaghost@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.6 --- messages-hive.options | 46 +++++++++++++ messages-hive.proto | 149 +++++++++++++++++++++++++++++++++++++++++ messages-solana.proto | 5 +- messages-tron.proto | 1 + messages-zcash.options | 4 -- messages-zcash.proto | 36 ++++------ messages.proto | 12 ++++ package-lock.json | 113 ++++++++++++++++++++----------- package.json | 8 +-- yarn.lock | 76 +++++++++++++-------- 10 files changed, 349 insertions(+), 101 deletions(-) create mode 100644 messages-hive.options create mode 100644 messages-hive.proto diff --git a/messages-hive.options b/messages-hive.options new file mode 100644 index 00000000..e878f3e3 --- /dev/null +++ b/messages-hive.options @@ -0,0 +1,46 @@ +HiveGetPublicKey.address_n max_count:8 + +HivePublicKey.public_key max_size:64 +HivePublicKey.raw_public_key max_size:33 + +HiveGetPublicKeys.account_index int_size:IS_32 + +HivePublicKeys.owner_key max_size:64 +HivePublicKeys.active_key max_size:64 +HivePublicKeys.memo_key max_size:64 +HivePublicKeys.posting_key max_size:64 + +HiveSignTx.address_n max_count:8 +HiveSignTx.chain_id max_size:32 +HiveSignTx.from max_size:16 +HiveSignTx.to max_size:16 +HiveSignTx.amount int_size:IS_64 +HiveSignTx.asset_symbol max_size:10 +HiveSignTx.memo max_size:2048 + +HiveSignedTx.signature max_size:65 +HiveSignedTx.serialized_tx max_size:512 + +HiveSignAccountCreate.address_n max_count:8 +HiveSignAccountCreate.chain_id max_size:32 +HiveSignAccountCreate.creator max_size:16 +HiveSignAccountCreate.new_account_name max_size:16 +HiveSignAccountCreate.owner_key max_size:64 +HiveSignAccountCreate.active_key max_size:64 +HiveSignAccountCreate.posting_key max_size:64 +HiveSignAccountCreate.memo_key max_size:64 +HiveSignAccountCreate.fee_amount int_size:IS_64 + +HiveSignedAccountCreate.signature max_size:65 +HiveSignedAccountCreate.serialized_tx max_size:512 + +HiveSignAccountUpdate.address_n max_count:8 +HiveSignAccountUpdate.chain_id max_size:32 +HiveSignAccountUpdate.account max_size:16 +HiveSignAccountUpdate.new_owner_key max_size:64 +HiveSignAccountUpdate.new_active_key max_size:64 +HiveSignAccountUpdate.new_posting_key max_size:64 +HiveSignAccountUpdate.new_memo_key max_size:64 + +HiveSignedAccountUpdate.signature max_size:65 +HiveSignedAccountUpdate.serialized_tx max_size:512 diff --git a/messages-hive.proto b/messages-hive.proto new file mode 100644 index 00000000..7612ec47 --- /dev/null +++ b/messages-hive.proto @@ -0,0 +1,149 @@ +syntax = "proto2"; + +option java_package = "com.shapeshift.keepkey.lib.protobuf"; +option java_outer_classname = "KeepKeyMessageHive"; + +/** + * Request: Ask device for a single Hive public key at a given SLIP-0048 path. + * Path format: m/48'/13'/role'/account'/0' + * role: 0'=owner 1'=active 3'=memo 4'=posting + * @start + * @next HivePublicKey + * @next Failure + */ +message HiveGetPublicKey { + repeated uint32 address_n = 1; // Full SLIP-0048 path (all 5 components hardened) + optional bool show_display = 2; // Confirm on device before returning + optional uint32 role = 3; // 0=owner 1=active 3=memo 4=posting (for display label only) +} + +/** + * Response: Single Hive public key + * @end + */ +message HivePublicKey { + optional string public_key = 1; // STM-prefixed base58check public key + optional bytes raw_public_key = 2; // 33-byte compressed secp256k1 public key +} + +/** + * Request: Ask device for all four Hive role keys in one interaction. + * Derives owner/active/memo/posting keys for the given account index. + * Paths: + * owner: m/48'/13'/0'/account_index'/0' + * active: m/48'/13'/1'/account_index'/0' + * memo: m/48'/13'/3'/account_index'/0' + * posting: m/48'/13'/4'/account_index'/0' + * @start + * @next HivePublicKeys + * @next Failure + */ +message HiveGetPublicKeys { + optional uint32 account_index = 1 [default = 0]; // Hive account slot (0 = first account) + optional bool show_display = 2; // Confirm on device before returning +} + +/** + * Response: All four Hive role public keys + * @end + */ +message HivePublicKeys { + optional string owner_key = 1; // STM... owner public key + optional string active_key = 2; // STM... active public key + optional string memo_key = 3; // STM... memo public key + optional string posting_key = 4; // STM... posting public key +} + +/** + * Request: Sign a Hive transfer transaction (op type 2). + * Signing key should be the active key: m/48'/13'/1'/account'/0' + * @start + * @next HiveSignedTx + * @next Failure + */ +message HiveSignTx { + repeated uint32 address_n = 1; // Full SLIP-0048 path of signing key + optional bytes chain_id = 2; // 32-byte chain ID (mainnet = beeab0de...) + optional uint32 ref_block_num = 3; // Reference block number (uint16) + optional uint32 ref_block_prefix = 4; // Reference block prefix (uint32) + optional uint32 expiration = 5; // Expiration Unix timestamp (uint32) + optional string from = 6; // Sender account name + optional string to = 7; // Recipient account name + optional uint64 amount = 8; // Amount in milliHIVE (1000 = 1.000 HIVE) + optional uint32 decimals = 9; // Decimal places (3 for HIVE/HBD) + optional string asset_symbol = 10; // "HIVE" or "HBD" + optional string memo = 11; // Optional transfer memo +} + +/** + * Response: Signed Hive transfer transaction + * @end + */ +message HiveSignedTx { + optional bytes signature = 1; // 65-byte recoverable secp256k1 signature + optional bytes serialized_tx = 2; // Serialized Graphene transaction bytes +} + +/** + * Request: Sign a Hive account_create operation (op type 9). + * All four role public keys become the account authorities at genesis. + * No software keys are generated. KeepKey is sole root of trust from block 1. + * Signing key: owner key at m/48'/13'/0'/account_index'/0' + * @start + * @next HiveSignedAccountCreate + * @next Failure + */ +message HiveSignAccountCreate { + repeated uint32 address_n = 1; // Owner key path (m/48'/13'/0'/account'/0') + optional bytes chain_id = 2; // 32-byte chain ID + optional uint32 ref_block_num = 3; + optional uint32 ref_block_prefix = 4; + optional uint32 expiration = 5; + optional string creator = 6; // Pioneer sponsor account name + optional string new_account_name = 7; // Desired Hive username + optional string owner_key = 8; // STM... owner public key (from device) + optional string active_key = 9; // STM... active public key (from device) + optional string posting_key = 10; // STM... posting public key (from device) + optional string memo_key = 11; // STM... memo public key (from device) + optional uint64 fee_amount = 12; // Creation fee in milliHIVE (3000 = 3.000 HIVE) +} + +/** + * Response: Signed Hive account_create transaction + * @end + */ +message HiveSignedAccountCreate { + optional bytes signature = 1; // 65-byte recoverable signature + optional bytes serialized_tx = 2; // Serialized Graphene transaction bytes +} + +/** + * Request: Sign a Hive account_update operation (op type 10). + * Replaces all account authorities with KeepKey-derived keys. + * Used to secure an existing Hive account. + * Signing key: owner key at m/48'/13'/0'/account_index'/0' + * @start + * @next HiveSignedAccountUpdate + * @next Failure + */ +message HiveSignAccountUpdate { + repeated uint32 address_n = 1; // Owner key path (must match account's current owner) + optional bytes chain_id = 2; // 32-byte chain ID + optional uint32 ref_block_num = 3; + optional uint32 ref_block_prefix = 4; + optional uint32 expiration = 5; + optional string account = 6; // Hive account name to update + optional string new_owner_key = 7; // STM... new owner public key + optional string new_active_key = 8; // STM... new active public key + optional string new_posting_key = 9; // STM... new posting public key + optional string new_memo_key = 10; // STM... new memo public key +} + +/** + * Response: Signed Hive account_update transaction + * @end + */ +message HiveSignedAccountUpdate { + optional bytes signature = 1; // 65-byte recoverable signature + optional bytes serialized_tx = 2; // Serialized Graphene transaction bytes +} diff --git a/messages-solana.proto b/messages-solana.proto index f0ca4484..a8f4eea2 100644 --- a/messages-solana.proto +++ b/messages-solana.proto @@ -91,10 +91,9 @@ message SolanaMessageSignature { * domain separation that plain SolanaSignMessage lacks. Firmware constructs * the envelope from the components below; host supplies version/format/message. * - * Format values: + * Format values (KeepKey supports formats 0 and 1 only; max message size 1212 bytes): * 0 = Restricted ASCII (printable, max 1212 bytes) — renderable on display * 1 = UTF-8 (max 1212 bytes) — renderable, may need policy gate - * 2 = UTF-8 (max 65515 bytes) — Ledger-only mode, blind-sign * * @next SolanaOffchainMessageSignature * @next Failure @@ -103,7 +102,7 @@ message SolanaSignOffchainMessage { repeated uint32 address_n = 1; // BIP-32/BIP-44 path to signing key optional string coin_name = 2 [default = "Solana"]; optional uint32 version = 3 [default = 0]; // Off-chain message spec version (0 = current) - optional uint32 message_format = 4; // 0=ASCII, 1=UTF8 limited, 2=UTF8 extended + optional uint32 message_format = 4; // 0=ASCII, 1=UTF8 (format 2 not supported) optional bytes message = 5; // Raw message payload (firmware wraps with envelope) optional bool show_display = 6; // Show message on device display } diff --git a/messages-tron.proto b/messages-tron.proto index f091c785..ffe9bbba 100644 --- a/messages-tron.proto +++ b/messages-tron.proto @@ -141,6 +141,7 @@ message TronSignTypedHash { /** * Response: Signed typed data * @prev TronSignTypedHash + * @end */ message TronTypedDataSignature { required string address = 1; // Base58Check TRON address that signed diff --git a/messages-zcash.options b/messages-zcash.options index 9e9f9992..31426964 100644 --- a/messages-zcash.options +++ b/messages-zcash.options @@ -35,10 +35,6 @@ ZcashTransparentInput.address_n max_count:8 ZcashTransparentSig.signature max_size:73 ZcashDisplayAddress.address_n max_count:8 -ZcashDisplayAddress.address max_size:256 -ZcashDisplayAddress.ak max_size:32 -ZcashDisplayAddress.nk max_size:32 -ZcashDisplayAddress.rivk max_size:32 ZcashDisplayAddress.expected_seed_fingerprint max_size:32 ZcashAddress.address max_size:256 diff --git a/messages-zcash.proto b/messages-zcash.proto index 10c13a2a..ac65c1c5 100644 --- a/messages-zcash.proto +++ b/messages-zcash.proto @@ -161,38 +161,30 @@ message ZcashTransparentSig { } /** - * Request: Display a Zcash unified address on the device screen. + * Request: Display the device-derived Orchard unified address on screen. * - * The host provides the unified address string and the FVK components - * (ak, nk, rivk) used to derive it. The device independently derives - * the FVK from the seed and verifies it matches the provided components - * before displaying the address with a QR code. + * The device derives the Orchard-only Unified Address (Sinsemilla + SWU + * hash-to-curve, default diversifier index 0) from its own seed at the + * requested account and shows it on the OLED with a QR code. What appears + * on screen is bound to this device — there is no host-supplied address + * to validate. * - * VERIFICATION SCOPE: The device only verifies that the Orchard FVK - * (ak, nk, rivk) in this request matches what it derives from the seed - * at the given account. A Unified Address may bundle receivers from - * multiple pools (transparent, Sapling, Orchard). The device CANNOT - * verify non-Orchard receivers — the guarantee is limited to: - * "This UA contains an Orchard receiver from this account." - * It does NOT guarantee that transparent or Sapling receivers (if - * present) are also controlled by this device. + * Either account or a complete address_n path (m/32'/133'/account', all + * hardened) is REQUIRED. The device rejects requests that omit both. * - * Full on-device UA derivation (Sinsemilla + SWU hash-to-curve) - * is planned for a future firmware release. - * - * Either account or a complete address_n path is REQUIRED. - * The device will reject requests that omit both. + * Fields 3–6 (host-supplied address, ak, nk, rivk) were removed when the + * device gained on-device UA derivation: FVK-match attestation against a + * host-built UA is strictly weaker than device-derived display and was + * dropped. Field numbers are reserved to prevent reuse. * * @next ZcashAddress * @next Failure */ message ZcashDisplayAddress { + reserved 3, 4, 5, 6; + reserved "address", "ak", "nk", "rivk"; repeated uint32 address_n = 1; // ZIP-32 path [32', 133', account'] — required if account omitted optional uint32 account = 2; // Account index — required if address_n omitted - optional string address = 3; // Host-computed unified address ("u1...") - optional bytes ak = 4; // 32-byte ak for Orchard FVK verification - optional bytes nk = 5; // 32-byte nk for Orchard FVK verification - optional bytes rivk = 6; // 32-byte rivk for Orchard FVK verification optional bytes expected_seed_fingerprint = 7; // 32-byte ZIP-32 §6.1 seed fingerprint. // If present, device verifies match against its own // seed fingerprint and rejects with Failure on mismatch. diff --git a/messages.proto b/messages.proto index ca35898c..6a9fcc66 100644 --- a/messages.proto +++ b/messages.proto @@ -239,6 +239,18 @@ enum MessageType { MessageType_TonSignedTx = 1503 [ (wire_out) = true ]; MessageType_TonSignMessage = 1504 [ (wire_in) = true ]; MessageType_TonMessageSignature = 1505 [ (wire_out) = true ]; + + // Hive + MessageType_HiveGetPublicKey = 1600 [ (wire_in) = true ]; + MessageType_HivePublicKey = 1601 [ (wire_out) = true ]; + MessageType_HiveSignTx = 1602 [ (wire_in) = true ]; + MessageType_HiveSignedTx = 1603 [ (wire_out) = true ]; + MessageType_HiveGetPublicKeys = 1604 [ (wire_in) = true ]; + MessageType_HivePublicKeys = 1605 [ (wire_out) = true ]; + MessageType_HiveSignAccountCreate = 1606 [ (wire_in) = true ]; + MessageType_HiveSignedAccountCreate = 1607 [ (wire_out) = true ]; + MessageType_HiveSignAccountUpdate = 1608 [ (wire_in) = true ]; + MessageType_HiveSignedAccountUpdate = 1609 [ (wire_out) = true ]; } //////////////////// diff --git a/package-lock.json b/package-lock.json index a709fae2..11708cdd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,140 +1,164 @@ { "name": "@keepkey/device-protocol", - "version": "7.2.4", - "lockfileVersion": 1, + "version": "7.14.1", + "lockfileVersion": 3, "requires": true, - "dependencies": { - "@protobufjs/aspromise": { + "packages": { + "": { + "name": "@keepkey/device-protocol", + "version": "7.14.1", + "license": "ISC", + "dependencies": { + "google-protobuf": "^3.7.0-rc.2", + "pbjs": "^0.0.5" + }, + "devDependencies": { + "protobufjs": "^6.8.8", + "ts-protoc-gen": "^0.10.0" + } + }, + "node_modules/@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=", "dev": true }, - "@protobufjs/base64": { + "node_modules/@protobufjs/base64": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", "dev": true }, - "@protobufjs/codegen": { + "node_modules/@protobufjs/codegen": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", "dev": true }, - "@protobufjs/eventemitter": { + "node_modules/@protobufjs/eventemitter": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=", "dev": true }, - "@protobufjs/fetch": { + "node_modules/@protobufjs/fetch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", "dev": true, - "requires": { + "dependencies": { "@protobufjs/aspromise": "^1.1.1", "@protobufjs/inquire": "^1.1.0" } }, - "@protobufjs/float": { + "node_modules/@protobufjs/float": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=", "dev": true }, - "@protobufjs/inquire": { + "node_modules/@protobufjs/inquire": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=", "dev": true }, - "@protobufjs/path": { + "node_modules/@protobufjs/path": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=", "dev": true }, - "@protobufjs/pool": { + "node_modules/@protobufjs/pool": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=", "dev": true }, - "@protobufjs/utf8": { + "node_modules/@protobufjs/utf8": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=", "dev": true }, - "@types/long": { + "node_modules/@types/long": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.0.tgz", "integrity": "sha512-1w52Nyx4Gq47uuu0EVcsHBxZFJgurQ+rTKS3qMHxR1GY2T8c2AJYd6vZoZ9q1rupaDjU0yT+Jc2XTyXkjeMA+Q==", "dev": true }, - "@types/node": { + "node_modules/@types/node": { "version": "10.14.6", "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.6.tgz", "integrity": "sha512-Fvm24+u85lGmV4hT5G++aht2C5I4Z4dYlWZIh62FAfFO/TfzXtPpoLI6I7AuBWkIFqZCnhFOoTT7RjjaIL5Fjg==", "dev": true }, - "bytebuffer": { + "node_modules/bytebuffer": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/bytebuffer/-/bytebuffer-5.0.1.tgz", "integrity": "sha1-WC7qSxqHO20CCkjVjfhfC7ps/d0=", - "requires": { + "dependencies": { "long": "~3" }, - "dependencies": { - "long": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz", - "integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s=" - } + "engines": { + "node": ">=0.8" } }, - "commander": { + "node_modules/bytebuffer/node_modules/long": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz", + "integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s=", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/commander": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", - "requires": { + "dependencies": { "graceful-readlink": ">= 1.0.0" + }, + "engines": { + "node": ">= 0.6.x" } }, - "google-protobuf": { + "node_modules/google-protobuf": { "version": "3.7.1", "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.7.1.tgz", "integrity": "sha512-6fvlUey6cNKtWSEn1bt4CT4wc2EID1fVluHS1dOnqIlxyIu3cBid2BvWE8Rwl6wN+hRTgiAKhfyydAGV/weZYQ==" }, - "graceful-readlink": { + "node_modules/graceful-readlink": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=" }, - "long": { + "node_modules/long": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", "dev": true }, - "pbjs": { + "node_modules/pbjs": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/pbjs/-/pbjs-0.0.5.tgz", "integrity": "sha1-tMiOFarEVSygkiqmTNUzjv00R78=", - "requires": { + "dependencies": { "bytebuffer": "5.0.1", "commander": "2.9.0", "protocol-buffers-schema": "3.1.0" + }, + "bin": { + "pbjs": "cli.js" } }, - "protobufjs": { + "node_modules/protobufjs": { "version": "6.8.8", "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.8.8.tgz", "integrity": "sha512-AAmHtD5pXgZfi7GMpllpO3q1Xw1OYldr+dMUlAnffGTAhqkg72WdmSY71uKBF/JuyiKs8psYbtKrhi0ASCD8qw==", "dev": true, - "requires": { + "hasInstallScript": true, + "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", @@ -148,18 +172,29 @@ "@types/long": "^4.0.0", "@types/node": "^10.1.0", "long": "^4.0.0" + }, + "bin": { + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" } }, - "protocol-buffers-schema": { + "node_modules/protocol-buffers-schema": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.1.0.tgz", "integrity": "sha1-2KgZVJ6tPmvRievp5Q6WY2u8XMc=" }, - "ts-protoc-gen": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/ts-protoc-gen/-/ts-protoc-gen-0.9.0.tgz", - "integrity": "sha512-cFEUTY9U9o6C4DPPfMHk2ZUdIAKL91hZN1fyx5Stz3g56BDVOC7hk+r5fEMCAGaaIgi2akkT1a2hrxu1wo2Phg==", - "dev": true + "node_modules/ts-protoc-gen": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/ts-protoc-gen/-/ts-protoc-gen-0.10.0.tgz", + "integrity": "sha512-EEbgDWNHK3CvcNhmib94I4HMO23qLddjLRdXW8EUE11VJxbi3n5J0l2DiX/L1pijOaPTkbEoRK+zQinKgKGqsw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "google-protobuf": "^3.6.1" + }, + "bin": { + "protoc-gen-ts": "bin/protoc-gen-ts" + } } } } diff --git a/package.json b/package.json index e004b2d8..ab77a719 100644 --- a/package.json +++ b/package.json @@ -1,15 +1,15 @@ { "name": "@keepkey/device-protocol", - "version": "7.13.4", + "version": "7.14.1", "publishConfig": { "access": "public" }, "description": "The proto buffer files from the KeepKey device, packed for consumption by the client.", "scripts": { "clean": "rm -rf ./lib/*.js ./lib/*.ts", - "build": "npm run build:js && npm run build:json && npm run build:postprocess", - "build:js": "protoc --plugin=protoc-gen-ts=./node_modules/.bin/protoc-gen-ts --js_out=import_style=commonjs,binary:./lib --ts_out=./lib types.proto messages.proto messages-ethereum.proto messages-eos.proto messages-nano.proto messages-cosmos.proto messages-binance.proto messages-ripple.proto messages-tendermint.proto messages-thorchain.proto messages-osmosis.proto messages-mayachain.proto messages-solana.proto messages-tron.proto messages-ton.proto messages-zcash.proto", - "build:json": "pbjs --keep-case -t json ./types.proto ./messages.proto ./messages-ethereum.proto ./messages-eos.proto ./messages-nano.proto ./messages-cosmos.proto ./messages-binance.proto ./messages-ripple.proto ./messages-tendermint.proto ./messages-thorchain.proto ./messages-osmosis.proto ./messages-mayachain.proto ./messages-solana.proto ./messages-tron.proto ./messages-ton.proto ./messages-zcash.proto > ./lib/proto.json", + "build": "npm run build:js && npm run build:postprocess", + "build:js": "protoc --plugin=protoc-gen-ts=./node_modules/.bin/protoc-gen-ts --js_out=import_style=commonjs,binary:./lib --ts_out=./lib types.proto messages.proto messages-ethereum.proto messages-eos.proto messages-nano.proto messages-cosmos.proto messages-binance.proto messages-ripple.proto messages-tendermint.proto messages-thorchain.proto messages-osmosis.proto messages-mayachain.proto messages-solana.proto messages-tron.proto messages-ton.proto messages-zcash.proto messages-hive.proto", + "build:json": "pbjs --keep-case -t json ./types.proto ./messages.proto ./messages-ethereum.proto ./messages-eos.proto ./messages-nano.proto ./messages-cosmos.proto ./messages-binance.proto ./messages-ripple.proto ./messages-tendermint.proto ./messages-thorchain.proto ./messages-osmosis.proto ./messages-mayachain.proto ./messages-solana.proto ./messages-tron.proto ./messages-ton.proto > ./lib/proto.json", "build:postprocess": "find ./lib -name \"*.js\" -exec sed -i '' -e \"s/var global = Function(\\'return this\\')();/var global = (function(){ return this }).call(null);/g\" {} \\;", "prepublishOnly": "npm run build", "test": "echo \"Error: no test specified\" && exit 1" diff --git a/yarn.lock b/yarn.lock index c4f17406..aaaab881 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4,90 +4,105 @@ "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": version "1.1.2" - resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" + resolved "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz" + integrity sha1-m4sMxmPWaafY9vXQiToU00jzD78= "@protobufjs/base64@^1.1.2": version "1.1.2" - resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" + resolved "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz" + integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== "@protobufjs/codegen@^2.0.4": version "2.0.4" - resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" + resolved "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz" + integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== "@protobufjs/eventemitter@^1.1.0": version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" + resolved "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz" + integrity sha1-NVy8mLr61ZePntCV85diHx0Ga3A= "@protobufjs/fetch@^1.1.0": version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" + resolved "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz" + integrity sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU= dependencies: "@protobufjs/aspromise" "^1.1.1" "@protobufjs/inquire" "^1.1.0" "@protobufjs/float@^1.0.2": version "1.0.2" - resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" + resolved "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz" + integrity sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E= "@protobufjs/inquire@^1.1.0": version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" + resolved "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz" + integrity sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik= "@protobufjs/path@^1.1.2": version "1.1.2" - resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" + resolved "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz" + integrity sha1-bMKyDFya1q0NzP0hynZz2Nf79o0= "@protobufjs/pool@^1.1.0": version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" + resolved "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz" + integrity sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q= "@protobufjs/utf8@^1.1.0": version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" + resolved "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz" + integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA= "@types/long@^4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.0.tgz#719551d2352d301ac8b81db732acb6bdc28dbdef" + resolved "https://registry.npmjs.org/@types/long/-/long-4.0.0.tgz" + integrity sha512-1w52Nyx4Gq47uuu0EVcsHBxZFJgurQ+rTKS3qMHxR1GY2T8c2AJYd6vZoZ9q1rupaDjU0yT+Jc2XTyXkjeMA+Q== "@types/node@^10.1.0": - version "10.12.24" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.24.tgz#b13564af612a22a20b5d95ca40f1bffb3af315cf" + version "10.14.6" + resolved "https://registry.npmjs.org/@types/node/-/node-10.14.6.tgz" + integrity sha512-Fvm24+u85lGmV4hT5G++aht2C5I4Z4dYlWZIh62FAfFO/TfzXtPpoLI6I7AuBWkIFqZCnhFOoTT7RjjaIL5Fjg== bytebuffer@5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/bytebuffer/-/bytebuffer-5.0.1.tgz#582eea4b1a873b6d020a48d58df85f0bba6cfddd" + resolved "https://registry.npmjs.org/bytebuffer/-/bytebuffer-5.0.1.tgz" + integrity sha1-WC7qSxqHO20CCkjVjfhfC7ps/d0= dependencies: long "~3" commander@2.9.0: version "2.9.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" + resolved "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz" + integrity sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q= dependencies: graceful-readlink ">= 1.0.0" -google-protobuf@^3.6.1: - version "3.9.0" - resolved "https://registry.yarnpkg.com/google-protobuf/-/google-protobuf-3.9.0.tgz#1f33e51e7993ea51e758a82650ad4347273b9bc6" - -google-protobuf@^3.7.0-rc.2: - version "3.7.0-rc.2" - resolved "https://registry.yarnpkg.com/google-protobuf/-/google-protobuf-3.7.0-rc.2.tgz#a65e9216825065099c4ff243eee9e16e764cc2c9" +google-protobuf@^3.6.1, google-protobuf@^3.7.0-rc.2: + version "3.7.1" + resolved "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.7.1.tgz" + integrity sha512-6fvlUey6cNKtWSEn1bt4CT4wc2EID1fVluHS1dOnqIlxyIu3cBid2BvWE8Rwl6wN+hRTgiAKhfyydAGV/weZYQ== "graceful-readlink@>= 1.0.0": version "1.0.1" - resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" + resolved "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz" + integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU= long@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" + resolved "https://registry.npmjs.org/long/-/long-4.0.0.tgz" + integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== long@~3: version "3.2.0" - resolved "https://registry.yarnpkg.com/long/-/long-3.2.0.tgz#d821b7138ca1cb581c172990ef14db200b5c474b" + resolved "https://registry.npmjs.org/long/-/long-3.2.0.tgz" + integrity sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s= pbjs@^0.0.5: version "0.0.5" - resolved "https://registry.yarnpkg.com/pbjs/-/pbjs-0.0.5.tgz#b4c88e15aac4552ca0922aa64cd5338efd3447bf" + resolved "https://registry.npmjs.org/pbjs/-/pbjs-0.0.5.tgz" + integrity sha1-tMiOFarEVSygkiqmTNUzjv00R78= dependencies: bytebuffer "5.0.1" commander "2.9.0" @@ -95,7 +110,8 @@ pbjs@^0.0.5: protobufjs@^6.8.8: version "6.8.8" - resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.8.8.tgz#c8b4f1282fd7a90e6f5b109ed11c84af82908e7c" + resolved "https://registry.npmjs.org/protobufjs/-/protobufjs-6.8.8.tgz" + integrity sha512-AAmHtD5pXgZfi7GMpllpO3q1Xw1OYldr+dMUlAnffGTAhqkg72WdmSY71uKBF/JuyiKs8psYbtKrhi0ASCD8qw== dependencies: "@protobufjs/aspromise" "^1.1.2" "@protobufjs/base64" "^1.1.2" @@ -113,10 +129,12 @@ protobufjs@^6.8.8: protocol-buffers-schema@3.1.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/protocol-buffers-schema/-/protocol-buffers-schema-3.1.0.tgz#d8a819549ead3e6bd189ebe9e50e96636bbc5cc7" + resolved "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.1.0.tgz" + integrity sha1-2KgZVJ6tPmvRievp5Q6WY2u8XMc= ts-protoc-gen@^0.10.0: version "0.10.0" - resolved "https://registry.yarnpkg.com/ts-protoc-gen/-/ts-protoc-gen-0.10.0.tgz#f708d99be59ad0be6bdce6f4fe893ec41757d2c9" + resolved "https://registry.npmjs.org/ts-protoc-gen/-/ts-protoc-gen-0.10.0.tgz" + integrity sha512-EEbgDWNHK3CvcNhmib94I4HMO23qLddjLRdXW8EUE11VJxbi3n5J0l2DiX/L1pijOaPTkbEoRK+zQinKgKGqsw== dependencies: google-protobuf "^3.6.1"