Add full Chain 138 integration: 8 steps, chain spec, app-ethereum config, docs

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
defiQUG
2026-02-12 15:57:08 -08:00
parent 17020ba236
commit bee1d29d55
33 changed files with 1444 additions and 1 deletions

View File

@@ -0,0 +1,9 @@
# Step 7 — Wallet API
1. **wallet-api repo** — If Ethereum family already supports multiple chainIds, add **138** to validation and routing. Otherwise use:
- **validation.ethereum-chain138.ts** — Zod schema allowing chainId 138.
- **types.ethereum-chain138.ts** — Transaction types.
- **serializer.ethereum-chain138.ts** — Serialize/deserialize for JSON-RPC.
- In `packages/core/src/families/common.ts` ensure `FAMILIES` includes the family; in `validation.ts` and `serializer.ts` add the new type to the union.
2. **ledger-live repo** — Bump `@ledgerhq/wallet-api-core`, `-server`, `-client`. Add or extend **walletApiAdapter.chain138.ts** in `libs/ledger-live-common/src/families/ethereum/walletApiAdapter.ts` so WalletAPI transactions with chainId 138 map to LL transactions. Do not edit the generated `generated/walletApiAdapter.ts` by hand; add the source adapter and run the sync-families-dispatch script.
3. **Changelog**`pnpm changelog`, create changeset for `@ledgerhq/wallet-api-core` (minor), open PR.

View File

@@ -0,0 +1,45 @@
/**
* Step 7 — Wallet API: serialize/deserialize for JSON-RPC
* Target: wallet-api packages/core/src/families/ethereum/serializer.ts
*
* Ethereum family already has serialization; ensure chainId is preserved.
* When adding a new family, implement serializeTransaction/deserializeTransaction
* for the new type and add to the union in packages/core/src/families/serializer.ts.
*/
import type { RawEthereumTransaction } from "./types.ethereum-chain138";
import type { EthereumTransaction } from "./types.ethereum-chain138";
export function serializeEthereumTransaction(
tx: EthereumTransaction
): RawEthereumTransaction {
return {
family: "ethereum",
amount: tx.amount,
recipient: tx.recipient,
gasPrice: tx.gasPrice,
maxFeePerGas: tx.maxFeePerGas,
maxPriorityFeePerGas: tx.maxPriorityFeePerGas,
gasLimit: tx.gasLimit,
data: tx.data,
nonce: tx.nonce,
chainId: tx.chainId,
};
}
export function deserializeEthereumTransaction(
raw: RawEthereumTransaction
): EthereumTransaction {
return {
family: "ethereum",
amount: raw.amount,
recipient: raw.recipient,
gasPrice: raw.gasPrice,
maxFeePerGas: raw.maxFeePerGas,
maxPriorityFeePerGas: raw.maxPriorityFeePerGas,
gasLimit: raw.gasLimit,
data: raw.data,
nonce: raw.nonce,
chainId: raw.chainId,
};
}

View File

@@ -0,0 +1,33 @@
/**
* Step 7 — Wallet API: types for Ethereum family (Chain 138)
* Target: wallet-api packages/core/src/families/ethereum/types.ts
*
* Transaction and Raw transaction types. Chain 138 uses same shape as Ethereum;
* chainId 138 identifies the network.
*/
export interface EthereumTransaction {
family: "ethereum";
amount: string;
recipient: string;
gasPrice?: string;
maxFeePerGas?: string;
maxPriorityFeePerGas?: string;
gasLimit?: string;
data?: string;
nonce?: number;
chainId: number; // 138 for Defi Oracle Meta Mainnet
}
export interface RawEthereumTransaction {
family: "ethereum";
amount: string;
recipient: string;
gasPrice?: string;
maxFeePerGas?: string;
maxPriorityFeePerGas?: string;
gasLimit?: string;
data?: string;
nonce?: number;
chainId: number;
}

View File

@@ -0,0 +1,28 @@
/**
* Step 7 — Wallet API: validation (Zod) for Ethereum family with chainId 138
* Target: ledger-live wallet-api packages/core/src/families/ethereum/validation.ts
* (If Ledger adds Chain 138 to Ethereum family, ensure chainId 138 is allowed in schema.)
*
* Example: extend schemaRawEthereumTransaction to allow chainId 138.
*/
import { z } from "zod";
const CHAIN_ID_138 = 138;
export const schemaRawEthereumTransaction = z.object({
family: z.literal("ethereum"),
amount: z.string(),
recipient: z.string(),
gasPrice: z.string().optional(),
maxFeePerGas: z.string().optional(),
maxPriorityFeePerGas: z.string().optional(),
gasLimit: z.string().optional(),
data: z.string().optional(),
nonce: z.number().optional(),
chainId: z.number().refine((id) => id === 1 || id === CHAIN_ID_138, {
message: "chainId must be 1 (Ethereum) or 138 (Defi Oracle Meta Mainnet)",
}),
});
export type RawEthereumTransaction = z.infer<typeof schemaRawEthereumTransaction>;

View File

@@ -0,0 +1,32 @@
/**
* Step 7 — Wallet API: Ledger Wallet adapter (WalletAPI tx <-> LL tx)
* Target: ledger-live libs/ledger-live-common/src/families/ethereum/walletApiAdapter.ts
*
* If Chain 138 is exposed via Wallet API, ensure the adapter maps WalletAPI
* Ethereum transaction (with chainId 138) to Ledger Wallet Ethereum transaction.
* Add to the generated walletApiAdapter dispatch (via sync-families-dispatch script).
*/
/*
// Example: in libs/ledger-live-common/src/families/ethereum/walletApiAdapter.ts
export function fromWalletAPITransaction(
walletApiTx: WalletAPIEthereumTransaction
): EthereumTransaction {
return {
...walletApiTx,
chainId: walletApiTx.chainId ?? 138,
};
}
export function toWalletAPITransaction(
llTx: EthereumTransaction
): WalletAPIEthereumTransaction {
return {
...llTx,
chainId: llTx.chainId,
};
}
*/
export const ADAPTER_NOTE =
"Extend ethereum walletApiAdapter to handle chainId 138; register in sync-families-dispatch so generated walletApiAdapter.ts includes it.";