llms.txt
@mysten/sui v2.0 and a new dApp Kit are here! Check out the migration guide
Mysten Labs SDKs
CryptographySigners

Ledger Signer

Sign Sui transactions with a Ledger hardware wallet

The LedgerSigner signs Sui transactions and personal messages with a Ledger hardware wallet. The private key never leaves the device; you confirm each signature on the Ledger. The Ledger signer uses the Ed25519 scheme.

Installation

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

You also need a Ledger transport 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.

import Transport from '@ledgerhq/hw-transport-node-hid';
import SuiLedgerClient from '@mysten/ledgerjs-hw-app-sui';
import { LedgerSigner } from '@mysten/ledger-signer';
import { SuiGrpcClient } from '@mysten/sui/grpc';

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)

ParameterTypeDescription
derivationPathstringBIP-32 derivation path (Sui uses coin type 784)
ledgerClientSuiLedgerClientA SuiLedgerClient wrapping an open Ledger transport
suiClientClientWithCoreApiA 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.

import { Transaction } from '@mysten/sui/transactions';

// 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);

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 for the signing and verification API shared by all signers.

On this page