diff --git a/.changeset/chilled-badgers-warn.md b/.changeset/chilled-badgers-warn.md new file mode 100644 index 000000000..086d1cf33 --- /dev/null +++ b/.changeset/chilled-badgers-warn.md @@ -0,0 +1,5 @@ +--- +'@solana/wallet-adapter-ledger': patch +--- + +Adding ability to signMessage with Ledger adapter diff --git a/packages/wallets/ledger/src/adapter.ts b/packages/wallets/ledger/src/adapter.ts index 86e0957d2..cbe710fd4 100644 --- a/packages/wallets/ledger/src/adapter.ts +++ b/packages/wallets/ledger/src/adapter.ts @@ -12,10 +12,11 @@ import { WalletPublicKeyError, WalletReadyState, WalletSignTransactionError, + WalletSignMessageError, } from '@solana/wallet-adapter-base'; import type { PublicKey, Transaction } from '@solana/web3.js'; import './polyfills/index.js'; -import { getDerivationPath, getPublicKey, signTransaction } from './util.js'; +import { getDerivationPath, getPublicKey, signTransaction, signMessage } from './util.js'; export interface LedgerWalletAdapterConfig { derivationPath?: Buffer; @@ -142,6 +143,23 @@ export class LedgerWalletAdapter extends BaseSignerWalletAdapter { } } + async signMessage(message: Uint8Array): Promise { + try { + try { + const transport = this._transport; + if (!transport) throw new WalletNotConnectedError(); + + const signature = await signMessage(transport, Buffer.from(message.buffer), this._derivationPath); + return new Uint8Array(signature); + } catch (error: any) { + throw new WalletSignMessageError(error?.message, error); + } + } catch (error: any) { + this.emit('error', error); + throw error; + } + } + private _disconnected = () => { const transport = this._transport; if (transport) { diff --git a/packages/wallets/ledger/src/util.ts b/packages/wallets/ledger/src/util.ts index 4c01000bc..78fad51a4 100644 --- a/packages/wallets/ledger/src/util.ts +++ b/packages/wallets/ledger/src/util.ts @@ -30,6 +30,7 @@ function harden(n: number): number { const INS_GET_PUBKEY = 0x05; const INS_SIGN_MESSAGE = 0x06; +const INS_SIGN_MESSAGE_OFFCHAIN = 0x07; const P1_NON_CONFIRM = 0x00; const P1_CONFIRM = 0x01; @@ -62,6 +63,16 @@ export async function signTransaction( return await send(transport, INS_SIGN_MESSAGE, P1_CONFIRM, data); } +/** @internal */ +export async function signMessage(transport: Transport, message: Buffer, derivationPath: Buffer): Promise { + const paths = Buffer.alloc(1); + paths.writeUInt8(1, 0); + + const data = Buffer.concat([paths, derivationPath, message]); + + return await send(transport, INS_SIGN_MESSAGE_OFFCHAIN, P1_CONFIRM, data); +} + async function send(transport: Transport, instruction: number, p1: number, data: Buffer): Promise { let p2 = 0; let offset = 0;