From cad5cff25444efee21ac208e98d6f0daf585ca0e Mon Sep 17 00:00:00 2001 From: highlander Date: Wed, 8 Jul 2026 22:02:32 -0300 Subject: [PATCH] feat(eth): LoadClearsignSigner icon + persist fields (msg 117 v2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Grows the hand-written LoadClearsignSigner jspb + ethLoadClearsignSigner to carry the persistent-identity extensions (device-protocol 33521a8): icon=4 (bytes, 1bpp mono RLE <=384B), icon_width=5, icon_height=6, persist=7 (keep in device flash across reboots). All optional/back-compatible — an omitted icon/persist serializes nothing. Pairs with firmware feat/clearsign-persistent-identity-icons. --- packages/hdwallet-keepkey/src/ethereum.ts | 50 ++++++++++++++++++++++- packages/hdwallet-keepkey/src/keepkey.ts | 14 ++++++- 2 files changed, 61 insertions(+), 3 deletions(-) diff --git a/packages/hdwallet-keepkey/src/ethereum.ts b/packages/hdwallet-keepkey/src/ethereum.ts index 6bead61e..ed9fc2dd 100644 --- a/packages/hdwallet-keepkey/src/ethereum.ts +++ b/packages/hdwallet-keepkey/src/ethereum.ts @@ -215,6 +215,18 @@ class LoadClearsignSigner extends jspb.Message { setAlias(value: string): void { jspb.Message.setField(this, 3, value); } + setIcon(value: Uint8Array | string): void { + jspb.Message.setField(this, 4, value); + } + setIconWidth(value: number): void { + jspb.Message.setField(this, 5, value); + } + setIconHeight(value: number): void { + jspb.Message.setField(this, 6, value); + } + setPersist(value: boolean): void { + jspb.Message.setField(this, 7, value); + } serializeBinary(): Uint8Array { const writer = new jspb.BinaryWriter(); @@ -230,6 +242,14 @@ class LoadClearsignSigner extends jspb.Message { } const alias = jspb.Message.getFieldWithDefault(message, 3, "") as string; if (alias) writer.writeString(3, alias); + const icon = jspb.Message.getFieldWithDefault(message, 4, "") as Uint8Array | string; + if (icon && (typeof icon === "string" ? icon.length > 0 : icon.length > 0)) { + writer.writeBytes(4, icon); + writer.writeUint32(5, jspb.Message.getFieldWithDefault(message, 5, 0) as number); + writer.writeUint32(6, jspb.Message.getFieldWithDefault(message, 6, 0) as number); + } + const persist = jspb.Message.getFieldWithDefault(message, 7, false) as boolean; + if (persist) writer.writeBool(7, persist); } static deserializeBinary(bytes: Uint8Array): LoadClearsignSigner { @@ -247,6 +267,18 @@ class LoadClearsignSigner extends jspb.Message { case 3: jspb.Message.setField(msg, 3, reader.readString()); break; + case 4: + jspb.Message.setField(msg, 4, reader.readBytes()); + break; + case 5: + jspb.Message.setField(msg, 5, reader.readUint32()); + break; + case 6: + jspb.Message.setField(msg, 6, reader.readUint32()); + break; + case 7: + jspb.Message.setField(msg, 7, reader.readBool()); + break; default: reader.skipField(); break; @@ -500,13 +532,29 @@ export async function ethSignTx(transport: Transport, msg: core.ETHSignTx): Prom */ export async function ethLoadClearsignSigner( transport: Transport, - msg: { keyId: number; pubkey: Uint8Array; alias: string } + msg: { + keyId: number; + pubkey: Uint8Array; + alias: string; + /** Optional identity logo: 1bpp mono RLE bitmap, <= 384 bytes. */ + icon?: Uint8Array; + iconWidth?: number; + iconHeight?: number; + /** Keep the identity in device flash across reboots (until WipeDevice). */ + persist?: boolean; + } ): Promise<{ ok: true }> { return transport.lockDuring(async () => { const m = new LoadClearsignSigner(); m.setKeyId(msg.keyId); m.setPubkey(msg.pubkey); m.setAlias(msg.alias); + if (msg.icon && msg.icon.length > 0) { + m.setIcon(msg.icon); + m.setIconWidth(msg.iconWidth ?? 0); + m.setIconHeight(msg.iconHeight ?? 0); + } + if (msg.persist) m.setPersist(true); await transport.call(MESSAGETYPE_LOADCLEARSIGNSIGNER, m, { msgTimeout: core.LONG_TIMEOUT, omitLock: true, diff --git a/packages/hdwallet-keepkey/src/keepkey.ts b/packages/hdwallet-keepkey/src/keepkey.ts index bd267480..fbcd4ee5 100644 --- a/packages/hdwallet-keepkey/src/keepkey.ts +++ b/packages/hdwallet-keepkey/src/keepkey.ts @@ -1376,8 +1376,18 @@ export class KeepKeyHDWallet implements core.HDWallet, core.BTCWallet, core.ETHW return Eth.ethSignTx(this.transport, msg); } - /** Load a runtime EVM clear-sign signer into a device key slot (RAM-only, user-confirmed). KeepKey-specific. */ - public async loadClearsignSigner(msg: { keyId: number; pubkey: Uint8Array; alias: string }): Promise<{ ok: true }> { + /** Load a runtime EVM clear-sign signer into a device key slot (user-confirmed). KeepKey-specific. + * Optionally carries an identity logo (icon, 1bpp mono RLE <=384B) and persist=true to keep the + * identity in device flash across reboots (firmware 7.15+). */ + public async loadClearsignSigner(msg: { + keyId: number; + pubkey: Uint8Array; + alias: string; + icon?: Uint8Array; + iconWidth?: number; + iconHeight?: number; + persist?: boolean; + }): Promise<{ ok: true }> { return Eth.ethLoadClearsignSigner(this.transport, msg); }