From e9067a032b998e2560395ee6f2d76d3cdbeea19c Mon Sep 17 00:00:00 2001 From: highlander Date: Wed, 5 Aug 2026 18:10:24 -0300 Subject: [PATCH 1/8] =?UTF-8?q?ci:=20pin=20cimg/node:20.11=20=E2=80=94=20t?= =?UTF-8?q?he=20legacy=20circleci/node=20image=20ships=20node=2017?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit yarn install --frozen-lockfile fails on this branch with: @mapbox/node-pre-gyp@2.0.3: The engine "node" is incompatible with this module. Expected version ">=18". Got "17.2.0" The unpinned legacy circleci/node image resolves to node 17.2.0. master passes only because its older lockfile predates that transitive requirement; any lockfile refresh trips it. Pin a maintained image. --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b2d2f49f..034b0e8d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -3,7 +3,7 @@ version: 2 defaults: &defaults working_directory: ~/device-protocol docker: - - image: circleci/node + - image: cimg/node:20.11 jobs: build: From fbb483f1cadc6394d51566ca4be0cfe6daa40000 Mon Sep 17 00:00:00 2001 From: highlander Date: Wed, 5 Aug 2026 18:13:22 -0300 Subject: [PATCH 2/8] fix(zcash): move file options into the preamble so pbjs can parse The Ironwood enum was inserted above the file-level java_package / java_outer_classname options, leaving them after a top-level definition. protobufjs's parser rejects that outright: Error: illegal token 'option' (messages-zcash.proto, line 16) so 'npm run build' (build:json -> lib/proto.json) fails on this branch. protoc accepts either order, so the generated descriptors are unchanged; every other proto in the repo already declares options directly after syntax. Verified: pbjs now emits proto.json cleanly. --- messages-zcash.proto | 8 +- package-lock.json | 255 ++++++++++++++++++++++++++++++------------- 2 files changed, 185 insertions(+), 78 deletions(-) diff --git a/messages-zcash.proto b/messages-zcash.proto index 4dd54d38..f03848b7 100644 --- a/messages-zcash.proto +++ b/messages-zcash.proto @@ -7,15 +7,15 @@ syntax = "proto2"; +// Sugar for easier handling in Java +option java_package = "com.keepkey.deviceprotocol"; +option java_outer_classname = "KeepKeyMessageZcash"; + enum ZcashShieldedPool { ZCASH_SHIELDED_POOL_ORCHARD = 0; ZCASH_SHIELDED_POOL_IRONWOOD = 1; } -// 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) * diff --git a/package-lock.json b/package-lock.json index 7c35fddc..60628403 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,24 +1,41 @@ { "name": "@keepkey/device-protocol", "version": "7.14.1", - "lockfileVersion": 1, + "lockfileVersion": 3, "requires": true, - "dependencies": { - "@isaacs/fs-minipass": { + "packages": { + "": { + "name": "@keepkey/device-protocol", + "version": "7.14.1", + "license": "ISC", + "dependencies": { + "google-protobuf": "3.21.4", + "pbjs": "^0.0.5" + }, + "devDependencies": { + "grpc-tools": "1.13.1", + "protobufjs": "^6.8.8", + "ts-protoc-gen": "^0.10.0" + } + }, + "node_modules/@isaacs/fs-minipass": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", "dev": true, - "requires": { + "dependencies": { "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" } }, - "@mapbox/node-pre-gyp": { + "node_modules/@mapbox/node-pre-gyp": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-2.0.3.tgz", "integrity": "sha512-uwPAhccfFJlsfCxMYTwOdVfOz3xqyj8xYL3zJj8f0pb30tLohnnFPhLuqp4/qoEz8sNxe4SESZedcBojRefIzg==", "dev": true, - "requires": { + "dependencies": { "consola": "^3.2.3", "detect-libc": "^2.0.0", "https-proxy-agent": "^7.0.5", @@ -26,236 +43,307 @@ "nopt": "^8.0.0", "semver": "^7.5.3", "tar": "^7.4.0" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + }, + "engines": { + "node": ">=18" } }, - "@protobufjs/aspromise": { + "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 }, - "abbrev": { + "node_modules/abbrev": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-3.0.1.tgz", "integrity": "sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==", - "dev": true + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } }, - "agent-base": { + "node_modules/agent-base": { "version": "7.1.4", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", - "dev": true + "dev": true, + "engines": { + "node": ">= 14" + } }, - "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" + } + }, + "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" } }, - "chownr": { + "node_modules/chownr": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", - "dev": true + "dev": true, + "engines": { + "node": ">=18" + } }, - "commander": { + "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" } }, - "consola": { + "node_modules/consola": { "version": "3.4.2", "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", - "dev": true + "dev": true, + "engines": { + "node": "^14.18.0 || >=16.10.0" + } }, - "debug": { + "node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, - "requires": { + "dependencies": { "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "detect-libc": { + "node_modules/detect-libc": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "google-protobuf": { + "node_modules/google-protobuf": { "version": "3.21.4", "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.21.4.tgz", "integrity": "sha512-MnG7N936zcKTco4Jd2PX2U96Kf9PxygAPKBug+74LHzmHXmceN16MmRcdgZv+DGef/S9YvQAfRsNCn4cjf9yyQ==" }, - "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=" }, - "grpc-tools": { + "node_modules/grpc-tools": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/grpc-tools/-/grpc-tools-1.13.1.tgz", "integrity": "sha512-0sttMUxThNIkCTJq5qI0xXMz5zWqV2u3yG1kR3Sj9OokGIoyRBFjoInK9NyW7x5fH7knj48Roh1gq5xbl0VoDQ==", "dev": true, - "requires": { + "hasInstallScript": true, + "dependencies": { "@mapbox/node-pre-gyp": "^2.0.0" + }, + "bin": { + "grpc_tools_node_protoc": "bin/protoc.js", + "grpc_tools_node_protoc_plugin": "bin/protoc_plugin.js" } }, - "https-proxy-agent": { + "node_modules/https-proxy-agent": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", "dev": true, - "requires": { + "dependencies": { "agent-base": "^7.1.2", "debug": "4" + }, + "engines": { + "node": ">= 14" } }, - "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 }, - "minipass": { + "node_modules/minipass": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", - "dev": true + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } }, - "minizlib": { + "node_modules/minizlib": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", "dev": true, - "requires": { + "dependencies": { "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" } }, - "ms": { + "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, - "node-fetch": { + "node_modules/node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "dev": true, - "requires": { + "dependencies": { "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } } }, - "nopt": { + "node_modules/nopt": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/nopt/-/nopt-8.1.0.tgz", "integrity": "sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==", "dev": true, - "requires": { + "dependencies": { "abbrev": "^3.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "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", @@ -269,68 +357,87 @@ "@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=" }, - "semver": { + "node_modules/semver": { "version": "7.8.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", - "dev": true + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } }, - "tar": { + "node_modules/tar": { "version": "7.5.22", "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.22.tgz", "integrity": "sha512-MFO/QzvtAOmJbkhOaCTvbGcFN9L9b+JunIsDwaKljSOdcLMea3NJ1k9Usz/rjdfSXTq4dfzfeS7W4p4YOAAHeA==", "dev": true, - "requires": { + "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.1.0", "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" } }, - "tr46": { + "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "dev": true }, - "ts-protoc-gen": { + "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, - "requires": { + "dependencies": { "google-protobuf": "^3.6.1" + }, + "bin": { + "protoc-gen-ts": "bin/protoc-gen-ts" } }, - "webidl-conversions": { + "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", "dev": true }, - "whatwg-url": { + "node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "dev": true, - "requires": { + "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, - "yallist": { + "node_modules/yallist": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", - "dev": true + "dev": true, + "engines": { + "node": ">=18" + } } } } From c3046cdcc27944977c40616211bdaa1a3baae04e Mon Sep 17 00:00:00 2001 From: pastaghost Date: Sat, 22 Aug 2026 18:33:38 -0600 Subject: [PATCH 3/8] fix(protocol): address Copilot review on #112 - ci: include messages-near.proto in the descriptor-validation protoc run so the shipped NEAR schema is actually compiled, matching both package builds - solana: bound the KKSOLSW1 LUT fields (lut_account, lut_signature) and the SolanaTokenInfo attestation signature in messages-solana.options, so nanopb emits fixed-size fields instead of callbacks - zcash: document the Zcash wire v2 breaking migration at the top of messages-zcash.proto (1307 rename and reshape, transparent output/ack phase, ZcashDisplayAddress 3-6 removal, compact signatures, sapling_digest) - near: mark 1610-1613 and messages-near.proto as schema-only and not implemented by firmware 7.15/RC18, add messages-near.options, and move the Hive 1614-1617 IDs out from under the NEAR comment - hive: drop the duplicated legacy paragraph on HiveSignAccountCreate that contradicted the attestation contract --- .github/workflows/ci.yml | 1 + messages-hive.proto | 4 ---- messages-near.options | 19 ++++++++++++++++++ messages-near.proto | 7 +++++++ messages-solana.options | 4 ++++ messages-zcash.proto | 42 ++++++++++++++++++++++++++++++++++++++++ messages.proto | 10 +++++++++- 7 files changed, 82 insertions(+), 5 deletions(-) create mode 100644 messages-near.options diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2e901a1e..c7cb4db9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,6 +42,7 @@ jobs: types.proto messages.proto messages-binance.proto \ messages-cosmos.proto messages-eos.proto messages-ethereum.proto \ messages-hive.proto messages-mayachain.proto messages-nano.proto \ + messages-near.proto \ messages-osmosis.proto messages-ripple.proto messages-solana.proto \ messages-tendermint.proto messages-thorchain.proto messages-ton.proto \ messages-tron.proto messages-zcash.proto diff --git a/messages-hive.proto b/messages-hive.proto index 83f06abf..6d7b5902 100644 --- a/messages-hive.proto +++ b/messages-hive.proto @@ -99,10 +99,6 @@ message HiveSignedTx { * 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). * Attestation signing key: owner key at m/48'/13'/0'/account_index'/0' - * 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 diff --git a/messages-near.options b/messages-near.options new file mode 100644 index 00000000..7eb82f13 --- /dev/null +++ b/messages-near.options @@ -0,0 +1,19 @@ +# NEAR -- schema only; firmware 7.15 / RC18 ships no NEAR handler. +# Bounds are declared here so nanopb generates fixed-size fields (matching the +# limits documented in messages-near.proto) rather than callbacks whenever a +# firmware release does adopt this schema. + +NearGetAddress.address_n max_count:8 +NearGetAddress.coin_name max_size:21 + +NearAddress.address max_size:65 +NearAddress.public_key max_size:32 + +NearSignTx.address_n max_count:8 +NearSignTx.coin_name max_size:21 +NearSignTx.raw_tx max_size:1024 +NearSignTx.receiver_id max_size:65 +NearSignTx.action_display max_size:128 + +NearSignedTx.signature max_size:64 +NearSignedTx.public_key max_size:32 diff --git a/messages-near.proto b/messages-near.proto index c44b04dc..842f3a28 100644 --- a/messages-near.proto +++ b/messages-near.proto @@ -5,6 +5,13 @@ * Derivation path: m/44'/397'/0' (SLIP-0010 hardened-only) * Address: lowercase hex of 32-byte Ed25519 public key (implicit account) * Signing: Ed25519(SHA256(borsh_serialized_transaction)) + * + * STATUS: SCHEMA ONLY -- NOT IMPLEMENTED BY FIRMWARE 7.15 / RC18. + * This file exists so MessageType 1610-1613 stay allocated and the intended + * wire surface is reviewable. That release ships no NEAR handler and answers + * these requests with Failure_UnexpectedMessage. Hosts must not advertise NEAR + * support on the basis of these bindings. nanopb bounds live in + * messages-near.options so firmware can adopt the schema without a redesign. */ syntax = "proto2"; diff --git a/messages-solana.options b/messages-solana.options index fd945238..87386f11 100644 --- a/messages-solana.options +++ b/messages-solana.options @@ -6,10 +6,14 @@ SolanaSignTx.raw_tx max_size:1232 SolanaSignTx.token_info max_count:4 SolanaSignTx.schema_payload max_size:256 SolanaSignTx.schema_signature max_size:64 +SolanaSignTx.lut_account max_count:8 +SolanaSignTx.lut_account max_size:32 +SolanaSignTx.lut_signature max_size:64 SolanaSignTx.token_recipient_owner max_count:4 SolanaSignTx.token_recipient_owner max_size:32 SolanaTokenInfo.mint max_size:32 SolanaTokenInfo.symbol max_size:13 +SolanaTokenInfo.signature max_size:64 SolanaAddress.address max_size:45 SolanaSignedTx.signature max_size:64 SolanaSignMessage.address_n max_count:8 diff --git a/messages-zcash.proto b/messages-zcash.proto index f03848b7..9cda5968 100644 --- a/messages-zcash.proto +++ b/messages-zcash.proto @@ -3,6 +3,48 @@ * * Zcash shielded transaction signing via PCZT (Partially Constructed * Zcash Transaction) format. Supports Orchard spend authorization. + * + * --------------------------------------------------------------------------- + * BREAKING CHANGE -- Zcash wire protocol v2 (firmware 7.15 / RC18) + * --------------------------------------------------------------------------- + * + * Unlike the rest of this release, the Zcash surface is NOT backward + * compatible. Zcash shielded support shipped as a preview and had no stable + * host implementations, so the flow was corrected in place rather than + * duplicated behind new message IDs. A host written against Zcash v1 + * (firmware <= 7.14.x) will not interoperate with 7.15 and must be updated. + * + * 1. MessageType 1307 was renamed ZcashTransparentSig -> ZcashTransparentSigned + * and its shape changed from one signature per request + * (required bytes signature = 1; optional uint32 next_index = 2) + * to a single batched response (repeated bytes signatures = 1). + * The wire ID is unchanged, so a v1 host decodes 1307 into the wrong + * message. Generated symbol names change accordingly. + * + * 2. The transparent phase gained ZcashTransparentOutput (1310) and + * ZcashTransparentAck (1311). Transparent outputs are now streamed before + * inputs, and all inputs are buffered before any signature is emitted, + * because ZIP-244 per-input transparent sighashes commit to every + * transparent prevout, value, script, sequence and output. The device + * therefore computes the sighash itself: ZcashTransparentInput.sighash is + * demoted from required to optional and is REJECTED when present. + * + * 3. ZcashDisplayAddress fields 3-6 (address, ak, nk, rivk) were removed and + * reserved. FVK-match attestation against a host-built unified address is + * strictly weaker than device-derived display, so the device now derives + * and shows its own Orchard UA. A v1 host that sends those fields gets a + * Failure. Either account or a full address_n path is now REQUIRED. + * + * 4. ZcashPCZTAction.is_spend is REQUIRED by firmware 7.15, and + * ZcashSignedPCZT.signatures is compact: one 64-byte RedPallas signature + * per is_spend=true action in ascending action order, rather than one per + * action. A v1 host that indexes signatures by action index will read the + * wrong signature. + * + * 5. ZcashSignPCZT.sapling_digest is reserved for future Sapling support and + * is currently rejected when set. + * + * These semantics are pinned by tools/check_zcash_contract.py. */ syntax = "proto2"; diff --git a/messages.proto b/messages.proto index 9357211c..0936cebf 100644 --- a/messages.proto +++ b/messages.proto @@ -265,11 +265,19 @@ enum MessageType { MessageType_HiveSignAccountUpdate = 1608 [ (wire_in) = true ]; MessageType_HiveSignedAccountUpdate = 1609 [ (wire_out) = true ]; - // NEAR + // NEAR -- SCHEMA ONLY, NOT YET IMPLEMENTED BY FIRMWARE. + // These IDs and messages-near.proto define the intended NEAR wire surface so + // that 1610-1613 stay allocated and cannot be reused. Firmware 7.15 / RC18 + // ships NO NEAR handler, so a device on that release answers any of these + // requests with Failure_UnexpectedMessage. Hosts must not advertise NEAR + // support on the basis of these bindings; treat the schema as reserved until + // a firmware release documents NEAR as supported. MessageType_NearGetAddress = 1610 [ (wire_in) = true ]; MessageType_NearAddress = 1611 [ (wire_out) = true ]; MessageType_NearSignTx = 1612 [ (wire_in) = true ]; MessageType_NearSignedTx = 1613 [ (wire_out) = true ]; + + // Hive (continued) MessageType_HiveSignMessage = 1614 [ (wire_in) = true ]; MessageType_HiveSignedMessage = 1615 [ (wire_out) = true ]; MessageType_HiveSignOperations = 1616 [ (wire_in) = true ]; From 4aed2072225442b4b73eea9649dfa2488ff57afc Mon Sep 17 00:00:00 2001 From: pastaghost Date: Sat, 22 Aug 2026 18:43:33 -0600 Subject: [PATCH 4/8] fix(near): remove unauthenticated display fields from NearSignTx The Ed25519 signature covers only SHA256(raw_tx), so the host-supplied receiver_id and action_display were never bound to the bytes being signed. A malicious host could display a benign receiver and action while obtaining a signature over entirely different transaction bytes. Reserve tags 4 and 5 so no implementation can reintroduce them, and state the confirmation contract on the message: every value shown to the user is derived by the device from raw_tx, and a transaction the device cannot parse must be refused rather than displayed from host-provided text. A Borsh NearTransaction already carries signer_id, public_key, nonce, receiver_id, block_hash and the action list inside the signed bytes. --- messages-near.options | 2 -- messages-near.proto | 23 +++++++++++++++++++---- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/messages-near.options b/messages-near.options index 7eb82f13..8340b0c1 100644 --- a/messages-near.options +++ b/messages-near.options @@ -12,8 +12,6 @@ NearAddress.public_key max_size:32 NearSignTx.address_n max_count:8 NearSignTx.coin_name max_size:21 NearSignTx.raw_tx max_size:1024 -NearSignTx.receiver_id max_size:65 -NearSignTx.action_display max_size:128 NearSignedTx.signature max_size:64 NearSignedTx.public_key max_size:32 diff --git a/messages-near.proto b/messages-near.proto index 842f3a28..488678fe 100644 --- a/messages-near.proto +++ b/messages-near.proto @@ -44,17 +44,32 @@ message NearAddress { * * The host Borsh-serializes the full NearTransaction and sends raw bytes. * Firmware SHA256-hashes the bytes, signs with Ed25519, returns 64-byte signature. - * receiver_id and action_display are provided separately for on-screen confirmation. + * + * CONFIRMATION CONTRACT: every value shown to the user MUST be derived by the + * device from raw_tx. The signature covers only SHA256(raw_tx), so any + * host-supplied display string is unauthenticated: a malicious host could show + * a benign receiver and action while obtaining a signature over entirely + * different bytes. A Borsh NearTransaction carries signer_id, public_key, + * nonce, receiver_id, block_hash and the action list in the signed bytes + * themselves, so the device has everything it needs without trusting the host. + * + * Tags 4 and 5 previously carried host-supplied receiver_id and action_display + * for exactly that unsafe flow. They are reserved so no implementation can + * reintroduce them. A device that cannot parse a given transaction must refuse + * it rather than fall back to displaying host-provided text. * * @next NearSignedTx * @next Failure */ message NearSignTx { + reserved 4, 5; + reserved "receiver_id", "action_display"; repeated uint32 address_n = 1; // BIP-44 path to signing key optional string coin_name = 2 [default = "NEAR"]; - optional bytes raw_tx = 3; // Borsh-serialized NearTransaction (max 1024 bytes) - optional string receiver_id = 4; // Destination account for display (max 64 chars) - optional string action_display = 5; // Human-readable action summary for display + optional bytes raw_tx = 3; // Borsh-serialized NearTransaction (max 1024 bytes). + // Sole source of truth for on-screen confirmation: + // the device parses receiver_id and the action list + // out of these bytes before signing them. } /** From 8cf968768f27b496ad3c9e78f0e124299566cf8c Mon Sep 17 00:00:00 2001 From: pastaghost Date: Sat, 22 Aug 2026 19:10:27 -0600 Subject: [PATCH 5/8] fix(protocol): correct Hive name bounds and mark Ironwood schema-only Hive account names are 3-16 characters (Graphene fixed_string_16), but nanopb max_size includes the NUL terminator, so max_size:16 only admits 15 characters. A valid 16-character account name was truncated or rejected by the generated firmware structs. Size the five account-name fields at 17: HiveSignTx.from, HiveSignTx.to, HiveSignAccountCreate.creator/new_account_name, and HiveSignAccountUpdate.account. RC18 is Orchard-only, but ZcashSignPCZT tags 19-20 advertised Ironwood / transaction-v6 pool selection that no firmware in this release implements, so a host selecting Ironwood could not receive the behavior the schema implied. Mark ZCASH_SHIELDED_POOL_IRONWOOD and ironwood_digest SCHEMA ONLY on their declarations, document that 7.15/RC18 rejects a non-Orchard pool and a present ironwood_digest with Failure, and pin both markers plus the field declarations in tools/check_zcash_contract.py so the schema-only status cannot silently drift into an implied guarantee. --- messages-hive.options | 13 ++++++++----- messages-zcash.proto | 22 ++++++++++++++++++++-- tools/check_zcash_contract.py | 25 +++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 7 deletions(-) diff --git a/messages-hive.options b/messages-hive.options index d39d5921..cd127e91 100644 --- a/messages-hive.options +++ b/messages-hive.options @@ -1,3 +1,6 @@ +# Hive account names are 3-16 characters (Graphene fixed_string_16). nanopb +# max_size includes the NUL terminator, so those fields are sized 17. + HiveGetPublicKey.address_n max_count:8 HivePublicKey.public_key max_size:64 @@ -12,8 +15,8 @@ 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.from max_size:17 +HiveSignTx.to max_size:17 HiveSignTx.amount int_size:IS_64 HiveSignTx.asset_symbol max_size:10 HiveSignTx.memo max_size:2048 @@ -23,8 +26,8 @@ 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.creator max_size:17 +HiveSignAccountCreate.new_account_name max_size:17 HiveSignAccountCreate.owner_key max_size:64 HiveSignAccountCreate.active_key max_size:64 HiveSignAccountCreate.posting_key max_size:64 @@ -36,7 +39,7 @@ HiveSignedAccountCreate.serialized_tx max_size:512 HiveSignAccountUpdate.address_n max_count:8 HiveSignAccountUpdate.chain_id max_size:32 -HiveSignAccountUpdate.account max_size:16 +HiveSignAccountUpdate.account max_size:17 HiveSignAccountUpdate.new_owner_key max_size:64 HiveSignAccountUpdate.new_active_key max_size:64 HiveSignAccountUpdate.new_posting_key max_size:64 diff --git a/messages-zcash.proto b/messages-zcash.proto index 9cda5968..062d3dca 100644 --- a/messages-zcash.proto +++ b/messages-zcash.proto @@ -53,9 +53,17 @@ syntax = "proto2"; option java_package = "com.keepkey.deviceprotocol"; option java_outer_classname = "KeepKeyMessageZcash"; +/* + * Orchard-family shielded pool selector. + * + * ORCHARD is the only value firmware 7.15 / RC18 accepts. IRONWOOD is SCHEMA + * ONLY: that release implements no Ironwood/transaction-v6 support and rejects + * shielded_pool=IRONWOOD with Failure. The value is allocated here so it cannot + * be reused and so the intended NU6.3 surface is reviewable. + */ enum ZcashShieldedPool { ZCASH_SHIELDED_POOL_ORCHARD = 0; - ZCASH_SHIELDED_POOL_IRONWOOD = 1; + ZCASH_SHIELDED_POOL_IRONWOOD = 1; // SCHEMA ONLY -- rejected by firmware 7.15 / RC18 } /** @@ -95,8 +103,18 @@ message ZcashSignPCZT { // NU6.3 / transaction-v6 Orchard-family pool selection. The existing // orchard_* metadata fields describe the selected action bundle for wire // compatibility; ironwood_digest is the fifth v6 transaction component. + // + // SCHEMA ONLY -- NOT IMPLEMENTED BY FIRMWARE 7.15 / RC18. The RC18 contract + // is Orchard-only: that release accepts shielded_pool=ORCHARD (the default) + // and rejects any other pool, and rejects ironwood_digest when present, + // both with Failure. A host must not select Ironwood or send an Ironwood + // digest against RC18 and expect the behavior this schema implies. These + // fields are defined so tags 19-20 stay allocated and the intended NU6.3 + // surface is reviewable; the rejection is pinned by + // tools/check_zcash_contract.py. optional ZcashShieldedPool shielded_pool = 19 [default = ZCASH_SHIELDED_POOL_ORCHARD]; - optional bytes ironwood_digest = 20; // 32-byte Ironwood component digest (v6) + optional bytes ironwood_digest = 20; // SCHEMA ONLY -- 32-byte Ironwood component + // digest (v6); rejected by firmware 7.15 / RC18 // 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 diff --git a/tools/check_zcash_contract.py b/tools/check_zcash_contract.py index bc64d57c..a744f81a 100644 --- a/tools/check_zcash_contract.py +++ b/tools/check_zcash_contract.py @@ -67,4 +67,29 @@ def require_field(message, declaration): if not re.search(r"one per\s*// is_spend=true action", ZCASH): raise AssertionError("ZcashSignedPCZT must document compact real-spend signatures") + +# RC18 is Orchard-only. The Ironwood/transaction-v6 surface is defined so tags +# 19-20 and ZcashShieldedPool value 1 stay allocated, but no firmware in this +# release implements it. Keep the fields marked schema-only so a host cannot +# read them as supported behavior. +require_field("ZcashSignPCZT", r"optional ZcashShieldedPool shielded_pool = 19 \[default = ZCASH_SHIELDED_POOL_ORCHARD\];") +require_field("ZcashSignPCZT", r"optional bytes ironwood_digest = 20;") + +for pattern, description in [ + (r"^.*ZCASH_SHIELDED_POOL_IRONWOOD\s*=\s*1\s*;.*$", "the Ironwood pool value"), + (r"^.*ironwood_digest\s*=\s*20\s*;.*$", "the Ironwood digest field"), +]: + line = re.search(pattern, ZCASH, re.M) + if line is None: + raise AssertionError("missing declaration for %s" % description) + if "SCHEMA ONLY" not in line.group(0): + raise AssertionError( + "%s must be marked SCHEMA ONLY on its declaration line" % description + ) + +if not re.search(r"SCHEMA ONLY -- NOT IMPLEMENTED BY FIRMWARE 7\.15 / RC18", ZCASH): + raise AssertionError( + "ZcashSignPCZT must document that the Ironwood pool selection is schema-only" + ) + print("RC18 Zcash protocol contract: ok") From 63e3d118cb16cd9921691c74b11090d23fdceea0 Mon Sep 17 00:00:00 2001 From: pastaghost Date: Sun, 23 Aug 2026 09:32:04 -0600 Subject: [PATCH 6/8] fix(build): repair postprocessor, generate full artifacts, untrack lib output The build:postprocess sed matched only the generator's old single-line `var global = Function('return this')();`. The current protoc-gen-js emits a multi-line IIFE whose last resort is that same call, so the pattern silently stopped matching and the dynamic-function fallback shipped in published bindings -- it was present in all 12 generated files. Building a function from a string is blocked under strict CSP, which is where these bindings run. Replace the one-liner with tools/postprocess-lib.js, which rewrites the call itself rather than the surrounding block (covering both the legacy and current shapes) and then fails the build if any dynamic-function fallback survives. This also drops the `sed -i ''` invocation, which is BSD-only and fails on the GNU sed in CI and on Linux developer machines. prepare ran only build:js, so Git-based installs got JavaScript but no lib/proto.json -- that is produced by build:json and is present in published packages. Point prepare at the full build so both artifact sets exist. lib/ is gitignored generated output, but lib/messages-ripple_pb.js and its .d.ts were committed, creating a second stale-prone source of truth. Untrack both; they are regenerated by the build. lib/.keep stays. --- lib/messages-ripple_pb.d.ts | 179 ----- lib/messages-ripple_pb.js | 1425 ----------------------------------- package.json | 4 +- tools/postprocess-lib.js | 61 ++ 4 files changed, 63 insertions(+), 1606 deletions(-) delete mode 100644 lib/messages-ripple_pb.d.ts delete mode 100644 lib/messages-ripple_pb.js create mode 100644 tools/postprocess-lib.js diff --git a/lib/messages-ripple_pb.d.ts b/lib/messages-ripple_pb.d.ts deleted file mode 100644 index 3c47e1ca..00000000 --- a/lib/messages-ripple_pb.d.ts +++ /dev/null @@ -1,179 +0,0 @@ -// 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 deleted file mode 100644 index 296100ad..00000000 --- a/lib/messages-ripple_pb.js +++ /dev/null @@ -1,1425 +0,0 @@ -// 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/package.json b/package.json index 614daf16..6a0dce38 100644 --- a/package.json +++ b/package.json @@ -10,8 +10,8 @@ "build": "npm run build:js && npm run build:json && npm run build:postprocess", "build:js": "mkdir -p ./lib && ./node_modules/.bin/grpc_tools_node_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 messages-near.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 ./messages-hive.proto ./messages-near.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\" {} \\;", - "prepare": "npm run build:js", + "build:postprocess": "node tools/postprocess-lib.js", + "prepare": "npm run build", "prepublishOnly": "npm run build", "test": "echo \"Error: no test specified\" && exit 1" }, diff --git a/tools/postprocess-lib.js b/tools/postprocess-lib.js new file mode 100644 index 00000000..cc53efa4 --- /dev/null +++ b/tools/postprocess-lib.js @@ -0,0 +1,61 @@ +#!/usr/bin/env node +/* + * Strip the CSP-hostile dynamic-function fallback from the generated bindings. + * + * protoc-gen-js emits a global bootstrap whose last resort is + * `Function('return this')()`. Building a function from a string is blocked by + * any strict Content-Security-Policy, which is exactly where these bindings run + * (browser extensions and packaged wallet apps). + * + * The older generator emitted that call on a single line and a sed one-liner in + * package.json rewrote it. The current generator emits a multi-line IIFE + * instead, so that pattern silently stopped matching and the dynamic call + * shipped in published output. Replace the call itself rather than the + * surrounding block: that covers both the legacy and current shapes, and a + * future generator reflow cannot quietly reintroduce it. + * + * Also replaces the `sed -i ''` invocation, which is BSD-only and fails on the + * GNU sed present in CI and on Linux developer machines. + */ +'use strict'; + +const fs = require('fs'); +const path = require('path'); + +const LIB = path.join(__dirname, '..', 'lib'); +const NEEDLE = "Function('return this')()"; +const REPLACEMENT = 'globalThis'; +const RESIDUE = /Function\(\s*['"]return this['"]\s*\)/; + +if (!fs.existsSync(LIB)) { + console.error('postprocess: ./lib does not exist -- run build:js first'); + process.exit(1); +} + +const files = fs.readdirSync(LIB).filter((name) => name.endsWith('.js')); +if (files.length === 0) { + console.error('postprocess: ./lib contains no generated .js -- run build:js first'); + process.exit(1); +} + +let patched = 0; +for (const name of files) { + const file = path.join(LIB, name); + const before = fs.readFileSync(file, 'utf8'); + if (!before.includes(NEEDLE)) continue; + fs.writeFileSync(file, before.split(NEEDLE).join(REPLACEMENT)); + patched += 1; +} + +// The point of this step is that nothing dynamic survives it. Fail loudly +// rather than publish bindings that break under CSP. +const missed = files.filter((name) => + RESIDUE.test(fs.readFileSync(path.join(LIB, name), 'utf8')) +); +if (missed.length > 0) { + console.error('postprocess: dynamic-function fallback still present in:'); + for (const name of missed) console.error(` lib/${name}`); + process.exit(1); +} + +console.log(`postprocess: patched ${patched} of ${files.length} generated file(s)`); From bb5e43e05fb07d0e4f4958508fce5a105ecbaca7 Mon Sep 17 00:00:00 2001 From: pastaghost Date: Sun, 23 Aug 2026 09:35:43 -0600 Subject: [PATCH 7/8] fix(build): call protobufjs's pbjs by path and drop the shadowing pbjs dep build:json invoked the bare `pbjs` bin, but two installed packages declare it: protobufjs (whose CLI the --keep-case -t json flags actually belong to) and the unrelated pbjs@0.0.5. On a clean `npm ci` the latter wins the .bin link, and its vendored protocol-buffers-schema cannot parse `reserved`, so build:json died with "Expected = but found 3" on the first reserved range it met. Stale local node_modules linked protobufjs instead, which is why this never showed up locally or in publish -- and why the previous prepare, which ran only build:js, never exposed it. Invoke ./node_modules/protobufjs/bin/pbjs explicitly, matching how build:js already calls its generator by path, and remove pbjs from dependencies: nothing requires it at runtime and its only effect was shadowing the real binary. --- package-lock.json | 56 +---------------------------------------------- package.json | 5 ++--- yarn.lock | 38 -------------------------------- 3 files changed, 3 insertions(+), 96 deletions(-) diff --git a/package-lock.json b/package-lock.json index 60628403..c214841d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,8 +9,7 @@ "version": "7.14.1", "license": "ISC", "dependencies": { - "google-protobuf": "3.21.4", - "pbjs": "^0.0.5" + "google-protobuf": "3.21.4" }, "devDependencies": { "grpc-tools": "1.13.1", @@ -145,25 +144,6 @@ "node": ">= 14" } }, - "node_modules/bytebuffer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/bytebuffer/-/bytebuffer-5.0.1.tgz", - "integrity": "sha1-WC7qSxqHO20CCkjVjfhfC7ps/d0=", - "dependencies": { - "long": "~3" - }, - "engines": { - "node": ">=0.8" - } - }, - "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/chownr": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", @@ -173,17 +153,6 @@ "node": ">=18" } }, - "node_modules/commander": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", - "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", - "dependencies": { - "graceful-readlink": ">= 1.0.0" - }, - "engines": { - "node": ">= 0.6.x" - } - }, "node_modules/consola": { "version": "3.4.2", "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", @@ -224,11 +193,6 @@ "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.21.4.tgz", "integrity": "sha512-MnG7N936zcKTco4Jd2PX2U96Kf9PxygAPKBug+74LHzmHXmceN16MmRcdgZv+DGef/S9YvQAfRsNCn4cjf9yyQ==" }, - "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=" - }, "node_modules/grpc-tools": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/grpc-tools/-/grpc-tools-1.13.1.tgz", @@ -324,19 +288,6 @@ "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/pbjs": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/pbjs/-/pbjs-0.0.5.tgz", - "integrity": "sha1-tMiOFarEVSygkiqmTNUzjv00R78=", - "dependencies": { - "bytebuffer": "5.0.1", - "commander": "2.9.0", - "protocol-buffers-schema": "3.1.0" - }, - "bin": { - "pbjs": "cli.js" - } - }, "node_modules/protobufjs": { "version": "6.8.8", "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.8.8.tgz", @@ -363,11 +314,6 @@ "pbts": "bin/pbts" } }, - "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=" - }, "node_modules/semver": { "version": "7.8.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", diff --git a/package.json b/package.json index 6a0dce38..62f099fd 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "clean": "rm -rf ./lib/*.js ./lib/*.ts", "build": "npm run build:js && npm run build:json && npm run build:postprocess", "build:js": "mkdir -p ./lib && ./node_modules/.bin/grpc_tools_node_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 messages-near.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 ./messages-hive.proto ./messages-near.proto > ./lib/proto.json", + "build:json": "./node_modules/protobufjs/bin/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 ./messages-hive.proto ./messages-near.proto > ./lib/proto.json", "build:postprocess": "node tools/postprocess-lib.js", "prepare": "npm run build", "prepublishOnly": "npm run build", @@ -27,7 +27,6 @@ "ts-protoc-gen": "^0.10.0" }, "dependencies": { - "google-protobuf": "3.21.4", - "pbjs": "^0.0.5" + "google-protobuf": "3.21.4" } } diff --git a/yarn.lock b/yarn.lock index ce3c2145..42870913 100644 --- a/yarn.lock +++ b/yarn.lock @@ -95,25 +95,11 @@ agent-base@^7.1.2: resolved "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz" integrity sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ== -bytebuffer@5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/bytebuffer/-/bytebuffer-5.0.1.tgz" - integrity sha1-WC7qSxqHO20CCkjVjfhfC7ps/d0= - dependencies: - long "~3" - chownr@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz" integrity sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g== -commander@2.9.0: - version "2.9.0" - resolved "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz" - integrity sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q= - dependencies: - graceful-readlink ">= 1.0.0" - consola@^3.2.3: version "3.4.2" resolved "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz" @@ -136,11 +122,6 @@ google-protobuf@^3.6.1, google-protobuf@3.21.4: resolved "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.21.4.tgz" integrity sha512-MnG7N936zcKTco4Jd2PX2U96Kf9PxygAPKBug+74LHzmHXmceN16MmRcdgZv+DGef/S9YvQAfRsNCn4cjf9yyQ== -"graceful-readlink@>= 1.0.0": - version "1.0.1" - resolved "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz" - integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU= - grpc-tools@1.13.1: version "1.13.1" resolved "https://registry.npmjs.org/grpc-tools/-/grpc-tools-1.13.1.tgz" @@ -161,11 +142,6 @@ long@^4.0.0: 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.npmjs.org/long/-/long-3.2.0.tgz" - integrity sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s= - minipass@^7.0.4, minipass@^7.1.2: version "7.1.3" resolved "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz" @@ -197,15 +173,6 @@ nopt@^8.0.0: dependencies: abbrev "^3.0.0" -pbjs@^0.0.5: - version "0.0.5" - resolved "https://registry.npmjs.org/pbjs/-/pbjs-0.0.5.tgz" - integrity sha1-tMiOFarEVSygkiqmTNUzjv00R78= - dependencies: - bytebuffer "5.0.1" - commander "2.9.0" - protocol-buffers-schema "3.1.0" - protobufjs@^6.8.8: version "6.8.8" resolved "https://registry.npmjs.org/protobufjs/-/protobufjs-6.8.8.tgz" @@ -225,11 +192,6 @@ protobufjs@^6.8.8: "@types/node" "^10.1.0" long "^4.0.0" -protocol-buffers-schema@3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.1.0.tgz" - integrity sha1-2KgZVJ6tPmvRievp5Q6WY2u8XMc= - semver@^7.5.3: version "7.8.5" resolved "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz" From f54f0a7dabb2d38c6f423bf6b6a68e8f979b1b53 Mon Sep 17 00:00:00 2001 From: highlander Date: Mon, 24 Aug 2026 22:54:32 -0500 Subject: [PATCH 8/8] feat(solana): carry certified ClearSign delegate certificate --- messages-solana.options | 1 + messages-solana.proto | 22 ++++++++++++++++++---- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/messages-solana.options b/messages-solana.options index 87386f11..f037ce33 100644 --- a/messages-solana.options +++ b/messages-solana.options @@ -11,6 +11,7 @@ SolanaSignTx.lut_account max_size:32 SolanaSignTx.lut_signature max_size:64 SolanaSignTx.token_recipient_owner max_count:4 SolanaSignTx.token_recipient_owner max_size:32 +SolanaSignTx.clearsign_certificate max_size:139 SolanaTokenInfo.mint max_size:32 SolanaTokenInfo.symbol max_size:13 SolanaTokenInfo.signature max_size:64 diff --git a/messages-solana.proto b/messages-solana.proto index 312b1481..8dc41433 100644 --- a/messages-solana.proto +++ b/messages-solana.proto @@ -74,10 +74,14 @@ message SolanaSignTx { * replayed onto another transaction, and it is domain-tagged so a * signature made for any other purpose cannot be replayed as one. * - * This is annotation, not authority: the accounts are displayed as - * PROVIDER-ATTESTED alongside the provider's alias, and the normal - * unverified-transaction review still runs. Rendering nothing while - * signing is the outcome this replaces. + * Runtime-loaded signers are annotation only: the accounts are displayed + * as PROVIDER-ATTESTED and the normal Advanced Mode blind-sign review still + * runs. A KeepKey root certificate scoped to Solana may instead authorize + * firmware to use the resolved keys while parsing the exact message. That + * certified path still requires a signed, structurally-complete KKSOLSC1 + * schema before the raw/blind review can be omitted. Self-contained + * legacy/v0 messages omit fields 5-7 because every account is already in + * raw_tx; their certified authority covers the schema only. * * Preimage: "KeepKeySolanaTxAccounts/1" || message_hash(32) * || count(le32) || account[0..count-1] (32 bytes each) @@ -114,6 +118,16 @@ message SolanaSignTx { * their payTo address without trusting host-side decoding or chain RPC. */ repeated bytes token_recipient_owner = 12; // 32-byte Solana public keys (max 4) + /* + * KeepKey root certificate for the delegate that signed the instruction + * schema and, when the message contains address lookups, the LUT account + * binding. The certificate uses the fixed 139-byte ClearSign delegation + * format and MUST be scoped to Solana (scope id 501). schema_signer_key_id + * and any present lut_signer_key_id MUST use the reserved delegate sentinel + * (0x80). Firmware rejects partial, mixed-runtime/certified, wrong-scope, + * invalid, missing-required-LUT, or unexpected-LUT requests. + */ + optional bytes clearsign_certificate = 13; } /**