# Ledger Blockchain Integration — Complete Reference (All Steps) **Last Updated:** 2026-02-13 **Purpose:** Full 8-step Ledger Wallet blockchain integration with gaps filled. Use for Defi Oracle Meta Mainnet (Chain ID 138) or any EVM chain. **Public code review for Ledger team:** [**bis-innovations/LedgerLive**](https://github.com/bis-innovations/LedgerLive) — use this repo for all Chain 138 integration code, specs, and patches intended for Ledger Live team review. **See also:** [ADD_CHAIN138_TO_LEDGER_LIVE](ADD_CHAIN138_TO_LEDGER_LIVE.md) for the Chain 138–specific action plan and submission text. **Generated code for all 8 steps:** [step-01-currency/](../step-01-currency/) through [step-08-manual-tests/](../step-08-manual-tests/). **Gaps and missing integrations (tests, fixes, checklist):** [GAPS_AND_MISSING_INTEGRATIONS.md](../GAPS_AND_MISSING_INTEGRATIONS.md). --- ## Prerequisites (do first) 1. **Agreement with Ledger** — [Submit the form](https://tally.so/r/mORpv8). Do **not** start development before they respond. 2. **Device app** — Either Ledger builds it (option A) or you/partner build + security audit (option B). See [Device App Kit](https://developers.ledger.com/docs/device-app/getting-started). 3. **Repos** — Fork/clone [LedgerHQ/ledger-live](https://github.com/LedgerHQ/ledger-live). For **public code review by the Ledger team**, publish your work to [**bis-innovations/LedgerLive**](https://github.com/bis-innovations/LedgerLive). Requirements for ledger-live: Node 18, pnpm 8, Python 2.7 or 3.5+, C/C++ toolchain. Run `pnpm i` in `ledger-live`. For **EVM chains (e.g. Chain 138):** The Ethereum device app already supports multiple chain IDs; Ledger may only need to add Chain 138 to the official app-ethereum `network.c` (we have this in our fork). No separate device app is required unless Ledger specifies otherwise. --- ## Step 1 — Currency (Cryptoassets library) **Doc:** [1 - Currency](https://developers.ledger.com/docs/ledger-live/accounts/integration/blockchain/cryptoassets-library) Add the coin to **`@ledgerhq/cryptoassets`** in `libs/ledgerjs/packages/cryptoassets/src/currencies.ts` (or `.js`). **CryptoCurrency fields:** `id`, `name`, `ticker`, `managerAppName`, `coinType` (SLIP-44), `scheme`, `color`, `family`, `units` (first = main unit, last must have `magnitude: 0`), `explorerViews` (tx, address, token URLs with `$hash`, `$address`, `$contractAddress`). For EVM: set `ethereumLikeInfo: { chainId: number }`. **Chain 138 example:** ```javascript // In libs/ledgerjs/packages/cryptoassets/src/currencies.ts defi_oracle_meta_mainnet: { type: "CryptoCurrency", id: "defi_oracle_meta_mainnet", coinType: 60, // SLIP-44 Ethereum name: "Defi Oracle Meta Mainnet", managerAppName: "Ethereum", ticker: "ETH", countervalueTicker: "ETH", scheme: "defi-oracle-meta", color: "#627EEA", family: "ethereum", units: [ { name: "ETH", code: "ETH", magnitude: 18 }, { name: "wei", code: "wei", magnitude: 0 }, ], ethereumLikeInfo: { chainId: 138 }, explorerViews: [ { address: "https://explorer.d-bis.org/address/$address", tx: "https://explorer.d-bis.org/tx/$hash", token: "https://explorer.d-bis.org/token/$contractAddress?a=$address", }, ], }, ``` Explorer order: list from most to least preferred; Ledger Wallet uses the first as default. --- ## Step 2 — Device app lib (JS bindings) **Doc:** [2 - Device app lib](https://developers.ledger.com/docs/ledger-live/accounts/integration/blockchain/js-bindings) *(full content behind GitHub login)* **Purpose:** JavaScript/TypeScript library that talks to the device app (e.g. `hw-app-eth` for Ethereum). Naming convention: `hw-app-*` (see `hw-app-btc`, `hw-app-eth` in the monorepo or on npm). **For EVM / Chain 138:** The existing **Ethereum app** and **`@ledgerhq/hw-app-eth`** already support any chain ID; signing uses EIP-155 and the chain ID is passed in the transaction. No new device app lib is required unless Ledger asks for a dedicated package. If they do: - Implement a class that extends or mirrors the Transport-based API (e.g. `getAddress(path, options)`, `signTransaction(path, rawTxHex)`, `signPersonalMessage(path, messageHex)`). - Publish or add to the monorepo under `libs/ledgerjs/packages/hw-app-*`. - The coin-module **signer** (Step 4) will call this lib. **If using Ethereum family:** Ensure `chainId: 138` is passed in transaction building and signing so the device displays the correct network. --- ## Step 3 — Create coin module **Doc:** [3 - Create module](https://developers.ledger.com/docs/ledger-live/accounts/integration/blockchain/create-module) Add a **CoinModule** under `libs/coin-modules/` (e.g. for a dedicated family) or reuse the **Ethereum** family. **For Chain 138 as Ethereum family:** Ledger typically adds new EVM chains by extending the existing **Ethereum** coin-module configuration (currency list, RPC, explorer) rather than creating a new `coin-defi_oracle_meta`. If Ledger requests a separate module: - **Layout:** `api/` (optional), `bridge/`, `logic/`, `network/`, `signer/`, `types/`, `config.ts`, `index.ts`. - **Rules:** One-way dependencies (e.g. `logic` must not import `bridge`). Use `index.ts` per folder to control exports. - **live-common:** Add or extend `libs/ledger-live-common/src/families/ethereum/` (or `families/defi_oracle_meta/` if separate) with setup, config, and walletApiAdapter. **Bridge** implements: sync, buildTransaction, signOperation, broadcast, getFeesForTransaction, getTransactionStatus, etc. **Network** wraps RPC/explorer (e.g. public RPCs and Blockscout for Chain 138). --- ## Step 4 — Derivation / signer **Doc:** [4 - Derivation / Signer](https://developers.ledger.com/docs/ledger-live/accounts/integration/blockchain/address-derivation) - Define **signer types** in the coin-module `types/signer.ts` (e.g. `getAddress(path, display?)`, `sign(path, message)` or transaction signing). - Implement **getAddress** in `signer/getAddress.ts` using `@ledgerhq/coin-framework` (`GetAddressFn`, `SignerContext`, `GetAddressOptions`); return `{ address, publicKey, path }`. - **EVM standard:** Derivation path `44'/60'/0'/0/0`; no custom overrides needed unless Ledger specifies. **CLI check:** ```bash ledger-live getAddress --currency ethereum --path "44'/60'/0'/0/0" --derivationMode "" ``` For Chain 138, currency may be `ethereum` with chainId 138 in config, or a dedicated id once added. If you need **custom derivation:** extend `libs/coin-framework/src/derivation.ts` with `overridesDerivation`, `legacyDerivations`, `disableBIP44`, `seedIdentifierPath` for your family. See [LLC derivation](https://github.com/LedgerHQ/ledger-live/wiki/LLC:derivation). --- ## Step 5 — API **Doc:** [5 - API](https://developers.ledger.com/docs/ledger-live/accounts/integration/blockchain/api) *(full content behind GitHub login)* **Purpose:** Backend/API used by the coin-module and optionally by Ledger Wallet services: RPC, indexer, or explorer integration for sync, fees, broadcast, and history. **For Chain 138:** - **RPC:** Use public endpoints (e.g. `https://rpc-http-pub.d-bis.org`, `https://rpc.d-bis.org`) for `eth_*` calls. See [ADD_CHAIN138_TO_LEDGER_LIVE § 3.1](../04-configuration/ADD_CHAIN138_TO_LEDGER_LIVE.md#31-chain-specification-chainlist-compatible) and `pr-workspace/chains/_data/chains/eip155-138.json`. - **Explorer:** Blockscout at `https://explorer.d-bis.org` (EIP3091). Use for tx/address/token links and, if needed, for history or verification. - Ledger may run their own indexer or proxy; they will specify. Have public RPC and explorer URLs ready for their config. --- ## Step 6 — LLD & LLM (desktop and mobile) **Doc:** [6 - LLD & LLM](https://developers.ledger.com/docs/ledger-live/accounts/integration/blockchain/desktop-mobile) **Ledger Wallet Common (live-common):** - In `libs/ledger-live-common/src/families/ethereum/` (or your family): **`setup.ts`** — create Bridge with `createBridges(executeWithSigner(createSigner), getCurrencyConfig)`, export `bridge`, `resolver`, `cliTools`. - **Config:** Register coin config (e.g. `config_currency_defi_oracle_meta_mainnet`) with at least `status` and `node.url` (e.g. from env `API_DEFI_ORACLE_META_NODE` or Ledger’s env naming). **Ledger Wallet Desktop (LLD):** - In `live-common-set-supported-currencies.js` add the currency id (e.g. `defi_oracle_meta_mainnet`). - Add error translation keys in `static/i18n/en`. - Run: `pnpm dev:lld`. **Ledger Wallet Mobile (LLM):** - In `live-common-setup.js` add the currency. - Add error keys in `src/locales/en/common.json`. - Run: `pnpm dev:llm` (iOS, Mac); Android: `pnpm mobile android`; iOS: `pnpm mobile ios` or open `ios/ledgerlivemobile.xcworkspace`. --- ## Step 7 — Wallet API (Ledger Wallet API) **Doc:** [7 - Wallet API](https://developers.ledger.com/docs/ledger-live/accounts/integration/blockchain/ledger-services-kit) **In [LedgerHQ/wallet-api](https://github.com/LedgerHQ/wallet-api):** 1. Fork/clone; `pnpm i` and `pnpm dev`. 2. If adding a **new family:** create `packages/core/src/families/{COIN_FAMILY}/` with `validation.ts` (Zod, at least `schemaRaw{COIN_FAMILY}Transaction`), `types.ts` (`{COIN_FAMILY}Transaction`, `Raw{COIN_FAMILY}Transaction`), `serializer.ts` (serialize/deserialize for JSON-RPC). 3. In `packages/core/src/families/common.ts` add family name to `FAMILIES`. 4. Export in `packages/core/src/families/index.ts`; update `types.ts` and `validation.ts` and `serializer.ts` for the union `Transaction` and `schemaRawTransaction`. 5. Run `pnpm changelog`, create changeset for `@ledgerhq/wallet-api-core` (minor bump), open PR. **For EVM:** Chain 138 may be supported by extending the existing **Ethereum** family in wallet-api (e.g. allow chainId 138 in validation and routing). Ledger will confirm. **In Ledger Wallet (ledger-live):** - Bump `@ledgerhq/wallet-api-core`, `@ledgerhq/wallet-api-server`, `@ledgerhq/wallet-api-client`. - Add or extend **Wallet API adapter** in `libs/ledger-live-common/src/families/ethereum/walletApiAdapter.ts` (or your family) so WalletAPI transaction type maps to Ledger Wallet transaction type. Ensure the adapter is included by the sync-families-dispatch script (do not edit generated file by hand; add the source adapter file). Example PRs: [Ethereum adapter](https://github.com/LedgerHQ/ledger-live/pull/3182), [Filecoin](https://github.com/LedgerHQ/wallet-api/pull/127), [Solana](https://github.com/LedgerHQ/wallet-api/pull/132). --- ## Step 8 — Manual tests **Doc:** [Manual tests](https://developers.ledger.com/docs/ledger-live/accounts/integration/blockchain/test-plan) - **Sync:** Add account; migrate account (add in prod, no crash); sync completes without error; big account (multi-page history). - **Receive / address:** Verify address with device; verify address without device. - **Balance:** Available balance correct. - **Broadcast:** Send max empties account; send amount correct; cannot send more than balance. - **Operations:** Optimistic operation correct; history complete; tx id correct; “View on explorer” works; operation account correct. - **Account:** Countervalue (fiat) correct if enabled; favorite works. --- ## Deployment checklist (all steps) | # | Step | Owner | Action | Done | |---|------|--------|--------|------| | 0 | Agreement | Project | Submit [form](https://tally.so/r/mORpv8); wait for Ledger response. | | | 0 | Device app | Ledger or us | For Chain 138: confirm Ethereum app + chainId 138 (our fork has it); or follow Device App Kit if Ledger requests. | | | 1 | Currency | Ledger / us | Add Chain 138 to `@ledgerhq/cryptoassets` (id, ethereumLikeInfo.chainId 138, explorerViews). | | | 2 | Device app lib | Ledger / us | For EVM: use `hw-app-eth`; ensure chainId 138 in tx building/signing. | | | 3 | Create module | Ledger / us | Use or extend Ethereum coin-module; config RPC + explorer for Chain 138. | | | 4 | Derivation/Signer | Ledger / us | Standard 44'/60'; getAddress + sign integrated. | | | 5 | API | Ledger / us | RPC + Blockscout URLs provided; Ledger may add indexer/config. | | | 6 | LLD & LLM | Ledger / us | live-common setup + config; LLD/LLM currency list + i18n; run dev and QA. | | | 7 | Wallet API | Ledger / us | wallet-api: Ethereum family supports chainId 138 or new family; LL adapter updated. | | | 8 | Manual tests | Ledger / us | Execute send/receive test plan (sync, receive, balance, broadcast, operations, account). | | --- ## Optional: tokens, swap, staking - **Tokens:** [Before you start](https://developers.ledger.com/docs/ledger-live/accounts/integration/tokens/before-you-start) → Device app → API → CAL; add integration/bot and manual tests. - **Swap:** Device app → Wallet API → Exchange SDK → Swap Live App → Ledger Wallet; manual + E2E. - **Staking:** [Strategy](https://developers.ledger.com/docs/ledger-live/accounts/integration/staking/strategy) → API → manual + E2E/integration/React/bot. --- ## Chain 138 quick reference | Item | Value | |------|--------| | Chain name | Defi Oracle Meta Mainnet | | Chain ID | 138 (0x8a) | | SLIP-44 | 60 (Ethereum) | | Derivation | 44'/60'/0'/0/0 | | Native | ETH, 18 decimals | | Public RPC | https://rpc-http-pub.d-bis.org, https://rpc.d-bis.org, etc. | | Explorer | https://explorer.d-bis.org (Blockscout, EIP3091) | | Chainlist | https://chainlist.org/chain/138 | | App-ethereum fork | `pr-workspace/app-ethereum` (network.c, defi_oracle.mk) | --- ## References - [Ledger – Adding your blockchain](https://developers.ledger.com/docs/ledger-live/accounts/getting-started) - [Ledger – Device App Kit](https://developers.ledger.com/docs/device-app/getting-started) - [Ledger – Blockchain integration form](https://tally.so/r/mORpv8) - [Ledger Live monorepo](https://github.com/LedgerHQ/ledger-live) - [Ledger App-Ethereum](https://github.com/LedgerHQ/app-ethereum) - [ADD_CHAIN138_TO_LEDGER_LIVE](../04-configuration/ADD_CHAIN138_TO_LEDGER_LIVE.md) — Chain 138 submission and materials