<img src="https://user-images.githubusercontent.com/4631227/191834116-59cf590e-25cc-4956-ae5c-812ea464f324.png" height="100" />

[GitHub](https://github.com/LedgerHQ/ledger-live/),
[Ledger Devs Discord](https://developers.ledger.com/discord-pro),
[Developer Portal](https://developers.ledger.com/)

## @ledgerhq/hw-app-canton

Ledger Hardware Wallet Canton JavaScript bindings.

***

## Are you adding Ledger support to your software wallet?

You may be using this package to communicate with the Canton Nano App.

For a smooth and quick integration:

*   See the developers’ documentation on the [Developer Portal](https://developers.ledger.com/docs/transport/overview/) and
*   Go on [Discord](https://developers.ledger.com/discord-pro/) to chat with developer support and the developer community.

## API

<!-- Generated by documentation.js. Update this documentation by updating the source code. -->

#### Table of Contents

*   [Canton](#canton)
    *   [Parameters](#parameters)
    *   [getAddress](#getaddress)
        *   [Parameters](#parameters-1)
    *   [signTransaction](#signtransaction)
        *   [Parameters](#parameters-2)
    *   [getAppConfiguration](#getappconfiguration)
*   [encodeDamlTransaction](#encodedamltransaction)
    *   [Parameters](#parameters-3)
*   [encodeInputContract](#encodeinputcontract)
    *   [Parameters](#parameters-4)
*   [encodeMetadata](#encodemetadata)
    *   [Parameters](#parameters-5)
*   [encodeNode](#encodenode)
    *   [Parameters](#parameters-6)
*   [rootInstance](#rootinstance)
*   [splitTransaction](#splittransaction)
    *   [Parameters](#parameters-7)
*   [CantonTransactionJson](#cantontransactionjson)

### Canton

Canton BOLOS API

#### Parameters

*   `transport` **Transport**&#x20;
*   `scrambleKey`   (optional, default `"canton_default_scramble_key"`)

#### getAddress

Get a Canton address for a given BIP-32 path.

##### Parameters

*   `path` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** a path in BIP-32 format
*   `display` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** whether to display the address on the device (optional, default `false`)

Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\<CantonAddress>** the address and public key

#### signTransaction

Sign a Canton transaction
using the appropriate signing method based on transaction type.

##### Parameters

*   `path` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** a path in BIP-32 format
*   `data` **(CantonPreparedTransaction | CantonUntypedVersionedMessage | [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String))** either prepared transaction components, untyped versioned message, or txHash string (backwards compatibility)

Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\<CantonSignature>** the signature

#### getAppConfiguration

Get the app configuration.

Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\<AppConfig>** the app configuration including version

### encodeDamlTransaction

Encode DAML transaction to protobuf bytes

#### Parameters

*   `data` **CantonTransactionData**&#x20;

Returns **[Uint8Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array)**&#x20;

### encodeInputContract

Encode input contract to protobuf bytes

#### Parameters

*   `contract` **CantonInputContract**&#x20;

Returns **[Uint8Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array)**&#x20;

### encodeMetadata

Encode metadata to protobuf bytes

#### Parameters

*   `data` **CantonTransactionMetadata**&#x20;
*   `inputContractsCount` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)**&#x20;

Returns **[Uint8Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array)**&#x20;

### encodeNode

Encode transaction node to protobuf bytes

#### Parameters

*   `node` **CantonTransactionNode**&#x20;

Returns **[Uint8Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array)**&#x20;

### rootInstance

Shared protobuf root instance.
Created once at module load time to avoid expensive re-parsing of the JSON schema.
The protobuf Root.fromJSON operation is expensive as it parses and validates
the entire schema, so we memoize it at module level.

Type: (Root | null)

### splitTransaction

Splits a Canton transaction into components for prepared transaction signing.
Converts protobuf transaction data into structured components that can be
sent to the Ledger device for signing.

#### Parameters

*   `transaction` **[CantonTransactionJson](#cantontransactionjson)** The transaction JSON structure from the Gateway API

Returns **CantonPreparedTransaction** Prepared transaction components ready for device signing

### CantonTransactionJson

Type definitions for Canton transaction JSON structure
These types represent the structure of transaction data from the Gateway API
that needs to be split into device-compatible components.

## Integration tests

### 1. Prerequisite

Download latest version of Ledger SDK.

```sh
docker pull ghcr.io/ledgerhq/ledger-app-builder/ledger-app-dev-tools:latest
```

The rest of the documentation is about testing on NanoSP.

### 2. Compile app-canton

You have to [compile](https://github.com/ledgerhq/app-canton) or retrieve the app binaries.

From the `app-canton` directory, compile for NanoSP:

```sh
docker run --rm -ti --privileged -v "$(pwd):/app" -w /app ghcr.io/ledgerhq/ledger-app-builder/ledger-app-dev-tools:latest bash -c 'export BOLOS_SDK=$NANOSP_SDK && make clean && make DEBUG=1'
```

The compiled binary will be at `build/nanosp/bin/app.elf`. In the following steps, `<ABSOLUTE_PATH_TO_ELFS>` should point to the directory containing the `build` folder (or wherever you've placed the compiled `app.elf` file).

### 3. Launch CantonApp within Speculos

```sh
docker run --rm -t -d --name speculos -v "<ABSOLUTE_PATH_TO_ELFS>:/app" -p 5000:5000 ghcr.io/ledgerhq/ledger-app-builder/ledger-app-dev-tools:latest

docker exec -it speculos bash -c 'speculos --model "nanosp" /app/build/nanosp/bin/app.elf --display headless'
```

### 4. Launch integration tests

From Ledger Live root directory:

```sh
pnpm ljs:hw-app-canton test-integ
```

You can take a look at [Speculos UI](http://127.0.0.1:5000/)

## Protobuf Integration

The Canton hardware app uses a binary protocol for all communication between Ledger Live and Ledger hardware devices.
It leverages Protocol Buffers (protobuf) to split complex DAML data structures into a compact binary format that the device can process efficiently.
Compared to JSON, this binary format significantly reduces data transfer size and processing time while preserving type safety and data integrity.
Get more info: [APDU](https://github.com/LedgerHQ/app-canton/blob/develop/doc/APDU.md), [SPLIT\_TRANSACTION](https://github.com/LedgerHQ/app-canton/blob/develop/doc/SPLIT_TRANSACTION.md)

### When to Use

After updating protobuf definitions in:

*   [gateway](https://github.com/LedgerHQ/canton-protos-scala)
*   [app-canton](https://github.com/LedgerHQ/app-canton)

you must regenerate the TypeScript bindings.

```bash
cd libs/ledgerjs/packages/hw-app-canton
pnpm generate-proto
```

### Protobuf Generation Process

The generate-proto script temporarily downloads `.proto` files and processes them, fixes reserved words and naming conflicts, and then generates TypeScript bindings using protobufjs.

The compiled definitions are saved to:

*   `src/types/transaction-proto.json` - JSON bindings for runtime use

### Key Protobuf Files

#### Core Device Communication

*   **`device.proto`** - Primary device communication protocol
    *   Defines the main interface for Ledger device communication
    *   Contains message types for transaction signing and address derivation
    *   Handles device-specific operations and responses

#### DAML Value System

*   **`value.proto`** - DAML value types and structures

    *   Defines all DAML data types (Unit, Bool, Int64, Date, Timestamp, Numeric, Party, Text, ContractId, Optional, List, TextMap, GenMap, Record, Variant, Enum)
    *   Handles DAML's type system for smart contract data

*   **`value_cb.proto`** - Canton Bridge value types
    *   Canton-specific extensions to DAML value types
    *   Additional types for Canton's privacy-preserving features
    *   Bridge-specific data structures and metadata

#### Interactive Transaction Submission

*   **`interactive_submission_common_data.proto`** - Common submission data structures and metadata
*   **`interactive_submission_data.proto`** - Transaction submission structure with versioning
*   **`interactive_submission_data_cb.proto`** - Canton Bridge extensions for consensus mechanism

#### Google Protobuf Standard Types

Standard Google protobuf files providing basic types for message containers, time handling, error reporting, and gRPC status codes used throughout the Canton module.

### Testing

To verify the protobuf bindings and transaction splitting logic, run the tests:

```bash
pnpm test tests/splitTransaction.test.ts
```

These tests validate protobuf serialization, and the logic that splits DAML transactions into device-compatible components.

Test data is stored in:

*   `tests/fixtures/prepare-transfer.json` — a sample transaction request (`token-transfer-request`) from the [Gateway API](https://canton-gateway.api.live.ledger-test.com/docs/openapi/redoc/index.html#operation/postV1NodeNode_preset_idPartyParty_idTransactionPrepare)
*   `tests/fixtures/prepare-transfer-serialized.json` — the expected serialized output, generated using [split\_tx\_util.py](https://github.com/LedgerHQ/app-canton/blob/develop/scripts/split_tx_util.py)
*   `prepare-transfer.apdus` - APDU command sequences recorded when signing prepare-transfer reponse

After updating protobuf bindings, make sure both files are refreshed with the latest Gateway data and serialized output.
