# Ledger Signer

> Sign Sui transactions with a Ledger hardware wallet

The `LedgerSigner` signs Sui transactions and personal messages with a
[Ledger](https://www.ledger.com/) hardware wallet. The private key never leaves the device; you
confirm each signature on the Ledger. The Ledger signer uses the `Ed25519` scheme.

## Installation

```sh npm2yarn
npm i @mysten/ledger-signer @mysten/ledgerjs-hw-app-sui
```

You also need a
[Ledger transport](https://github.com/LedgerHQ/ledger-live/tree/develop/libs/ledgerjs) for your
environment, for example `@ledgerhq/hw-transport-node-hid` in Node.js or
`@ledgerhq/hw-transport-webhid` in the browser.

## Creating a signer

Open a transport, wrap it in a `SuiLedgerClient`, then construct the signer with
`LedgerSigner.fromDerivationPath`. This is async: it fetches the public key from the device so the
signer can derive the Sui address.

```typescript

const transport = await Transport.open(undefined);
const ledgerClient = new SuiLedgerClient(transport);
const suiClient = new SuiGrpcClient({
	network: 'testnet',
	baseUrl: 'https://fullnode.testnet.sui.io:443',
});

const signer = await LedgerSigner.fromDerivationPath(
	"m/44'/784'/0'/0'/0'",
	ledgerClient,
	suiClient,
);
```

### Parameters

`fromDerivationPath(derivationPath, ledgerClient, suiClient)`

| Parameter        | Type                | Description                                           |
| ---------------- | ------------------- | ----------------------------------------------------- |
| `derivationPath` | `string`            | BIP-32 derivation path (Sui uses coin type `784`)     |
| `ledgerClient`   | `SuiLedgerClient`   | A `SuiLedgerClient` wrapping an open Ledger transport |
| `suiClient`      | `ClientWithCoreApi` | A Sui client used to resolve transaction data         |

## Usage

Derive the address, then sign a transaction or personal message. The user confirms each signature on
the device.

```typescript

// Derive the Sui address
const address = signer.toSuiAddress();

// Build and sign a transaction
const transaction = new Transaction();
const transactionBytes = await transaction.build({ client: suiClient });
const { signature } = await signer.signTransaction(transactionBytes);

// Or sign a personal message
const message = new TextEncoder().encode('Hello, Ledger Signer!');
await signer.signPersonalMessage(message);
```

> **Warning:** The Ledger signer supports only `signTransaction` and `signPersonalMessage`. It does not support
> the generic `sign` and `signWithIntent` methods, which throw an error because the device only
> signs recognized transaction and message payloads.

See [Cryptography](/sui/cryptography) for the signing and verification API shared by all signers.