Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/tidy-eagles-brand.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@ledgerhq/ledger-wallet-framework": minor
---

Add Zod branded `CryptoCurrencyId`/`TokenCurrencyId` types so a raw string can no longer be passed where a currency id is required without crossing an explicit validation boundary.
48 changes: 17 additions & 31 deletions apps/ledger-live-desktop/.oxlintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,8 @@
"suspicious": "warn",
"pedantic": "off"
},
"plugins": [
"eslint",
"import",
"oxc",
"unicorn",
"typescript",
"react",
"jest"
],
"ignorePatterns": [
"*.min.js",
"src/mvvm/hooks/redux.ts",
"tests/artifacts/**"
],
"plugins": ["eslint", "import", "oxc", "unicorn", "typescript", "react", "jest"],
"ignorePatterns": ["*.min.js", "src/mvvm/hooks/redux.ts", "tests/artifacts/**"],
"rules": {
"eslint/no-unused-vars": "warn",
"eslint/no-empty-pattern": "warn",
Expand Down Expand Up @@ -73,7 +61,11 @@
"Currency",
"Unit",
"FiatCurrency",
"ExplorerView"
"ExplorerView",
"CryptoCurrencyId",
"TokenCurrencyId",
"CryptoCurrencyIdSchema",
"TokenCurrencyIdSchema"
],
"message": "Wallet-framework currency types are for coin-modules. Import from @domain/entity-currency-* (unions from @domain/entity-currency)."
},
Expand All @@ -85,30 +77,26 @@
"Currency",
"Unit",
"FiatCurrency",
"ExplorerView"
"ExplorerView",
"CryptoCurrencyId",
"TokenCurrencyId",
"CryptoCurrencyIdSchema",
"TokenCurrencyIdSchema"
],
"message": "Wallet-framework currency types are for coin-modules. Import from @domain/entity-currency-* (unions from @domain/entity-currency)."
}
],
"patterns": [
{
"group": [
"@ledgerhq/live-common/lib/**",
"@ledgerhq/live-common/lib-es/**"
],
"group": ["@ledgerhq/live-common/lib/**", "@ledgerhq/live-common/lib-es/**"],
"message": "Please remove the /lib import from live-common import."
},
{
"group": [
"~/mvvm/**"
],
"group": ["~/mvvm/**"],
"message": "Use 'LLD' alias instead of '~/mvvm'. Replace '~/mvvm' with 'LLD' in your imports."
},
{
"group": [
"**/renderer/families/*/**",
"~/renderer/families/*/**"
],
"group": ["**/renderer/families/*/**", "~/renderer/families/*/**"],
"message": "families files must not be imported directly. use the bridge or export them through the LLDCoinFamily interface instead."
},
{
Expand Down Expand Up @@ -155,12 +143,10 @@
"env": {
"jest": true
},
"plugins": [
"jest"
],
"plugins": ["jest"],
"rules": {
"typescript/no-explicit-any": "warn"
}
}
]
}
}
56 changes: 25 additions & 31 deletions apps/ledger-live-mobile/.oxlintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,7 @@
"suspicious": "warn",
"pedantic": "off"
},
"plugins": [
"eslint",
"import",
"oxc",
"unicorn",
"typescript",
"react",
"jest",
"jsx-a11y"
],
"plugins": ["eslint", "import", "oxc", "unicorn", "typescript", "react", "jest", "jsx-a11y"],
"ignorePatterns": [
"*.min.js",
"node_modules",
Expand All @@ -41,10 +32,7 @@
"eslint/no-unused-expressions": "warn",
"eslint/no-unsafe-optional-chaining": "off",
"eslint/no-useless-rename": "warn",
"eslint/no-console": [
"error",
{ "allow": ["warn", "error"] }
],
"eslint/no-console": ["error", { "allow": ["warn", "error"] }],
"eslint/no-restricted-imports": [
"error",
{
Expand Down Expand Up @@ -73,7 +61,11 @@
"Currency",
"Unit",
"FiatCurrency",
"ExplorerView"
"ExplorerView",
"CryptoCurrencyId",
"TokenCurrencyId",
"CryptoCurrencyIdSchema",
"TokenCurrencyIdSchema"
],
"message": "Wallet-framework currency types are for coin-modules. Import from @domain/entity-currency-* (unions from @domain/entity-currency)."
},
Expand All @@ -85,17 +77,18 @@
"Currency",
"Unit",
"FiatCurrency",
"ExplorerView"
"ExplorerView",
"CryptoCurrencyId",
"TokenCurrencyId",
"CryptoCurrencyIdSchema",
"TokenCurrencyIdSchema"
],
"message": "Wallet-framework currency types are for coin-modules. Import from @domain/entity-currency-* (unions from @domain/entity-currency)."
}
],
"patterns": [
{
"group": [
"@ledgerhq/live-common/lib/**",
"@ledgerhq/live-common/lib-es/**"
],
"group": ["@ledgerhq/live-common/lib/**", "@ledgerhq/live-common/lib-es/**"],
"message": "Please remove the /lib import from live-common import."
},
{
Expand Down Expand Up @@ -159,11 +152,7 @@
},
"overrides": [
{
"files": [
"**/*.test.{ts,tsx}",
"**/__tests__/**",
"e2e/**/*.{ts,tsx}"
],
"files": ["**/*.test.{ts,tsx}", "**/__tests__/**", "e2e/**/*.{ts,tsx}"],
"env": { "jest": true },
"plugins": ["jest"],
"rules": {
Expand Down Expand Up @@ -197,7 +186,11 @@
"Currency",
"Unit",
"FiatCurrency",
"ExplorerView"
"ExplorerView",
"CryptoCurrencyId",
"TokenCurrencyId",
"CryptoCurrencyIdSchema",
"TokenCurrencyIdSchema"
],
"message": "Wallet-framework currency types are for coin-modules. Import from @domain/entity-currency-* (unions from @domain/entity-currency)."
},
Expand All @@ -209,17 +202,18 @@
"Currency",
"Unit",
"FiatCurrency",
"ExplorerView"
"ExplorerView",
"CryptoCurrencyId",
"TokenCurrencyId",
"CryptoCurrencyIdSchema",
"TokenCurrencyIdSchema"
],
"message": "Wallet-framework currency types are for coin-modules. Import from @domain/entity-currency-* (unions from @domain/entity-currency)."
}
],
"patterns": [
{
"group": [
"@ledgerhq/live-common/lib/**",
"@ledgerhq/live-common/lib-es/**"
],
"group": ["@ledgerhq/live-common/lib/**", "@ledgerhq/live-common/lib-es/**"],
"message": "Please remove the /lib import from live-common import."
},
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { renderHook, withReadOnlyDisabled, act } from "@tests/test-renderer";
import { CryptoCurrencyIdSchema } from "@domain/entity-currency-crypto";
import { NavigatorName, ScreenName } from "~/const";
import { State } from "~/reducers/types";
import { track } from "~/analytics";
Expand Down Expand Up @@ -167,7 +168,10 @@ describe("useTopBarViewModel", () => {
mockedUseSyncIndicator.mockReturnValue({
...defaultSyncState,
isError: true,
errorCurrencyIds: ["bitcoin", "ethereum"],
errorCurrencyIds: [
CryptoCurrencyIdSchema.parse("bitcoin"),
CryptoCurrencyIdSchema.parse("ethereum"),
],
});

const { result } = renderHook(() => useTopBarViewModel(mockNavigation as never));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export class CoinFrameworkAdapter {
const tokenAssets = balanceRes.filter(b => b.asset.type !== "native");

const tokenBalances = await Promise.all(
tokenAssets.map(async ({ asset, value }) => {
tokenAssets.map(async ({ asset, value }): Promise<Balance | null> => {
const token = await bridgeApi.getTokenFromAsset?.(asset);
if (!token) return null;
return { assetId: token.id, balance: BigNumberStrSchema.parse(String(value)) };
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import type { CryptoCurrency, TokenCurrency } from "@ledgerhq/ledger-wallet-framework/types";
import {
type CryptoCurrency,
type TokenCurrency,
CryptoCurrencyIdSchema,
TokenCurrencyIdSchema,
} from "@ledgerhq/ledger-wallet-framework/types";

export const MOCK_TOKEN_PROGRAM_ID = "usad_stablecoin.aleo";

export const getMockedCurrency = (overrides?: Partial<CryptoCurrency>): CryptoCurrency => {
return {
type: "CryptoCurrency",
id: "aleo",
id: CryptoCurrencyIdSchema.parse("aleo"),
coinType: 683,
name: "Aleo",
managerAppName: "Aleo",
Expand Down Expand Up @@ -33,9 +38,9 @@ export const getMockedCurrency = (overrides?: Partial<CryptoCurrency>): CryptoCu
export const getMockedTokenCurrency = (overrides?: Partial<TokenCurrency>): TokenCurrency => {
return {
type: "TokenCurrency",
id: "usad",
id: TokenCurrencyIdSchema.parse("usad"),
contractAddress: MOCK_TOKEN_PROGRAM_ID,
parentCurrencyId: "aleo",
parentCurrencyId: CryptoCurrencyIdSchema.parse("aleo"),
tokenType: "arc22",
name: "USAD",
ticker: "USAD",
Expand Down
6 changes: 5 additions & 1 deletion libs/coin-modules/coin-aleo/src/bridge/tokens.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import BigNumber from "bignumber.js";
import type { TokenAccount } from "@ledgerhq/types-live";
import { setCryptoAssetsStore } from "@ledgerhq/ledger-wallet-framework/cryptoAssetsStore";
import { TokenCurrencyIdSchema } from "@ledgerhq/ledger-wallet-framework/types";
import { encodeTokenAccountId } from "@ledgerhq/ledger-wallet-framework/account";
import { encodeAccountId } from "@ledgerhq/ledger-wallet-framework/account/accountId";
import { encodeOperationId } from "@ledgerhq/ledger-wallet-framework/operation";
Expand Down Expand Up @@ -270,7 +271,10 @@ describe("tokens utils", () => {

it("should append sub-accounts that do not exist on the initial account", () => {
const existingSubAccount = getMockedTokenAccount(mockTokenCurrency);
const newToken = getMockedTokenCurrency({ id: "other-token", contractAddress: "other.aleo" });
const newToken = getMockedTokenCurrency({
id: TokenCurrencyIdSchema.parse("other-token"),
contractAddress: "other.aleo",
});
const newSubAccount = getMockedTokenAccount(newToken);
const initialAccount = getMockedAccount({ subAccounts: [existingSubAccount] });

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { fetchAccountTransactionsFromHeight } from "../network/utils";
import { TokenCurrencyIdSchema } from "@ledgerhq/ledger-wallet-framework/types";
import { getMockedTransaction } from "../__tests__/fixtures/api.fixture";
import { getMockedConfig } from "../__tests__/fixtures/config.fixture";
import {
Expand Down Expand Up @@ -213,7 +214,7 @@ describe("listOperations", () => {
it("should include multiple token operations when several CAL tokens are present", async () => {
const secondProgramId = "usad_stablecoin.aleo";
const secondTokenCurrency = getMockedTokenCurrency({
id: "aleo/token/usad_stablecoin.aleo",
id: TokenCurrencyIdSchema.parse("aleo/token/usad_stablecoin.aleo"),
contractAddress: secondProgramId,
ticker: "USAD",
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { formatCurrencyUnit } from "@ledgerhq/coin-module-framework/currencies";
import { getCryptoAssetsStore } from "@ledgerhq/ledger-wallet-framework/cryptoAssetsStore";
import { getAccountCurrency } from "@ledgerhq/ledger-wallet-framework/account";
import type { CommonDeviceTransactionField as DeviceTransactionField } from "@ledgerhq/ledger-wallet-framework/transaction/common";
import { TokenCurrency } from "@ledgerhq/ledger-wallet-framework/types";
import type { TokenCurrency } from "@ledgerhq/ledger-wallet-framework/types";
import { AccountLike } from "@ledgerhq/types-live";
import { extractTokenId } from "./tokens";
import type { AlgorandTransaction, Transaction, TransactionStatus } from "./types";
Expand Down
14 changes: 10 additions & 4 deletions libs/coin-modules/coin-aptos/src/__tests__/bridge/logic.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { EntryFunctionPayloadResponse } from "@aptos-labs/ts-sdk";
import { setCryptoAssetsStore } from "@ledgerhq/ledger-wallet-framework/cryptoAssetsStore";
import {
TokenCurrencyIdSchema,
CryptoCurrencyIdSchema,
} from "@ledgerhq/ledger-wallet-framework/types";
import {
decodeTokenAccountId,
encodeTokenAccountId,
Expand Down Expand Up @@ -462,9 +466,9 @@ describe("Aptos sync logic", () => {
if (address === "0xd111::staked_coin::stakedaptos") {
return {
type: "TokenCurrency" as const,
id: "aptos/coin/dstapt::staked_coin::stakedaptos",
id: TokenCurrencyIdSchema.parse("aptos/coin/dstapt::staked_coin::stakedaptos"),
contractAddress: "0xd111::staked_coin::StakedAptos",
parentCurrencyId: "aptos",
parentCurrencyId: CryptoCurrencyIdSchema.parse("aptos"),
name: "dstAPT",
tokenType: "coin",
ticker: "dstAPT",
Expand Down Expand Up @@ -746,9 +750,11 @@ describe("Aptos sync logic", () => {
if (address === "0x2ebb") {
return {
type: "TokenCurrency" as const,
id: "aptos/fungible_asset/cellana_0x2ebb2ccac5e027a87fa0e2e5f656a3a4238d6a48d93ec9b610d570fc0aa0df12",
id: TokenCurrencyIdSchema.parse(
"aptos/fungible_asset/cellana_0x2ebb2ccac5e027a87fa0e2e5f656a3a4238d6a48d93ec9b610d570fc0aa0df12",
),
contractAddress: "0x2ebb",
parentCurrencyId: "aptos",
parentCurrencyId: CryptoCurrencyIdSchema.parse("aptos"),
name: "CELLANA",
tokenType: "fungible_asset",
ticker: "CELL",
Expand Down
Loading
Loading