Files
LedgerLive/docs/LEDGER_BLOCKCHAIN_INTEGRATION_COMPLETE.md

238 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 138specific 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 Ledgers 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