Skip to content

Commit

Permalink
chore: introduce live-wallet, decoupling user's data from Account type
Browse files Browse the repository at this point in the history
  • Loading branch information
gre committed Apr 25, 2024
1 parent 882c77d commit 9fb494b
Show file tree
Hide file tree
Showing 266 changed files with 3,757 additions and 3,182 deletions.
22 changes: 22 additions & 0 deletions .changeset/rude-tables-share.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
"@ledgerhq/types-live": patch
"@ledgerhq/coin-algorand": patch
"@ledgerhq/coin-polkadot": patch
"@ledgerhq/coin-bitcoin": patch
"@ledgerhq/coin-evm": patch
"@actions/build-checks": patch
"@ledgerhq/native-modules-tools": patch
"ledger-live-desktop": patch
"live-mobile": patch
"@ledgerhq/live-common": patch
"@ledgerhq/ethereum-provider": patch
"@ledgerhq/dummy-wallet-app": patch
"@ledgerhq/wallet-api-exchange-module": patch
"@ledgerhq/coin-framework": patch
"@ledgerhq/live-nft-react": patch
"@ledgerhq/live-wallet": patch
"@ledgerhq/live-cli": patch
"@ledgerhq/live-env": patch
---

Drop technical Account#name and Account#starred fields and replace it with a new architecture: a wallet store that contains all user's data.
1 change: 1 addition & 0 deletions apps/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"@ledgerhq/live-config": "workspace:^",
"@ledgerhq/live-countervalues": "workspace:^",
"@ledgerhq/live-env": "workspace:^",
"@ledgerhq/live-wallet": "workspace:^",
"@ledgerhq/live-network": "workspace:^",
"@ledgerhq/logs": "workspace:^",
"@ledgerhq/types-devices": "workspace:^",
Expand Down
9 changes: 3 additions & 6 deletions apps/cli/src/commands/blockchain/derivation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import {
getDerivationScheme,
} from "@ledgerhq/coin-framework/derivation";
import { setEnv, getEnv } from "@ledgerhq/live-env";
import { getAccountPlaceholderName } from "@ledgerhq/live-common/account/index";
import { getDefaultAccountNameForCurrencyIndex } from "@ledgerhq/live-wallet/accountName";

export default {
args: [],
job: () =>
Expand All @@ -32,11 +33,7 @@ export default {
" " +
(derivationMode || "default") +
": " +
getAccountPlaceholderName({
currency,
index: 0,
derivationMode,
}) +
getDefaultAccountNameForCurrencyIndex({ currency, index: 0 }) +
": " +
path
);
Expand Down
5 changes: 3 additions & 2 deletions apps/cli/src/commands/blockchain/estimateMaxSpendable.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { concat, from } from "rxjs";
import { concatMap } from "rxjs/operators";
import { getAccountBridge } from "@ledgerhq/live-common/bridge/index";
import { getAccountUnit, getAccountName } from "@ledgerhq/live-common/account/index";
import { getAccountUnit } from "@ledgerhq/live-common/account/index";
import { formatCurrencyUnit } from "@ledgerhq/live-common/currencies/index";
import { scan, scanCommonOpts } from "../../scan";
import type { ScanCommonOpts } from "../../scan";
import { getDefaultAccountName } from "@ledgerhq/live-wallet/accountName";

const format = (account, value) => {
const unit = getAccountUnit(account);
const name = getAccountName(account);
const name = getDefaultAccountName(account);
const amount = formatCurrencyUnit(unit, value, {
showCode: true,
disableRounding: true,
Expand Down
3 changes: 2 additions & 1 deletion apps/cli/src/commands/blockchain/generateTestTransaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { getAccountBridge } from "@ledgerhq/live-common/bridge/index";
import type { InferTransactionsOpts } from "../../transaction";
import { inferTransactions, inferTransactionsOpts } from "../../transaction";
import type { SignedOperation } from "@ledgerhq/types-live";
import { getDefaultAccountNameForCurrencyIndex } from "@ledgerhq/live-wallet/accountName";

const toJS = obj => {
if (typeof obj === "object" && obj) {
Expand Down Expand Up @@ -118,7 +119,7 @@ ${apdus.map(a => " " + a).join("\n")}
reduce((jsCodes, code) => jsCodes.concat(code), []),
map(
codes => `{
name: "${account.name}",
name: "${getDefaultAccountNameForCurrencyIndex(account)}",
raw: ${JSON.stringify(
toAccountRaw({
...account,
Expand Down
4 changes: 3 additions & 1 deletion apps/cli/src/commands/live/balanceHistory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import { formatCurrencyUnit } from "@ledgerhq/live-common/currencies/index";
import { scan, scanCommonOpts } from "../../scan";
import type { ScanCommonOpts } from "../../scan";
import type { PortfolioRange } from "@ledgerhq/types-live";
import { getDefaultAccountNameForCurrencyIndex } from "@ledgerhq/live-wallet/accountName";

const histoFormatters = {
default: (histo, account) =>
histo
Expand All @@ -29,7 +31,7 @@ const histoFormatters = {
asciichart: (history, account) =>
"\n" +
"".padStart(22) +
account.name +
getDefaultAccountNameForCurrencyIndex(account) +
": " +
formatCurrencyUnit(account.unit, account.balance, {
showCode: true,
Expand Down
4 changes: 3 additions & 1 deletion apps/cli/src/commands/live/exportAccounts.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { of, interval } from "rxjs";
import { reduce, mergeMap, shareReplay, tap } from "rxjs/operators";
import { dataToFrames } from "qrloop";
import { encode } from "@ledgerhq/live-common/cross";
import { encode } from "@ledgerhq/live-wallet/liveqr/cross";
import { asQR } from "../../qr";
import { scan, scanCommonOpts } from "../../scan";
import type { ScanCommonOpts } from "../../scan";
import { Account } from "@ledgerhq/types-live";
import { initialState } from "@ledgerhq/live-wallet/store";
export default {
description: "Export given accounts to Live QR or console for importing",
args: [
Expand All @@ -27,6 +28,7 @@ export default {
reduce<Account, Account[]>((accounts, account) => accounts.concat(account), []),
mergeMap(accounts => {
const data = encode({
walletState: initialState,
accounts,
settings: {
pairExchanges: {},
Expand Down
12 changes: 7 additions & 5 deletions apps/cli/src/commands/live/portfolio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { from } from "rxjs";
import { reduce, concatMap, map } from "rxjs/operators";
import type { Account, PortfolioRange } from "@ledgerhq/types-live";
import type { Currency } from "@ledgerhq/types-cryptoassets";
import { flattenAccounts, getAccountName } from "@ledgerhq/live-common/account/index";
import { flattenAccounts } from "@ledgerhq/live-common/account/index";
import { getPortfolio, getRanges } from "@ledgerhq/live-countervalues/portfolio";
import { formatCurrencyUnit, findCurrencyByTicker } from "@ledgerhq/live-common/currencies/index";
import { scan, scanCommonOpts } from "../../scan";
Expand All @@ -15,6 +15,7 @@ import {
loadCountervalues,
inferTrackingPairForAccounts,
} from "@ledgerhq/live-countervalues/logic";
import { getDefaultAccountName } from "@ledgerhq/live-wallet/accountName";

function asPortfolioRange(period: string): PortfolioRange {
const ranges = getRanges();
Expand Down Expand Up @@ -114,14 +115,15 @@ export default {

let str = "";
accounts.forEach(top => {
str += render("Account " + getAccountName(top), [top]);
str += render("Account " + getDefaultAccountName(top), [top]);
str += "\n";

if (top.subAccounts) {
top.subAccounts.forEach(sub => {
str += render("Account " + getAccountName(top) + " > " + getAccountName(sub), [
sub,
]).replace(/\n/s, " \n");
str += render(
"Account " + getDefaultAccountName(top) + " > " + getDefaultAccountName(sub),
[sub],
).replace(/\n/s, " \n");
str += "\n";
});
}
Expand Down
9 changes: 1 addition & 8 deletions apps/cli/src/scan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ import getAppAndVersion from "@ledgerhq/live-common/hw/getAppAndVersion";
import { withDevice } from "@ledgerhq/live-common/hw/deviceAccess";
import { delay } from "@ledgerhq/live-common/promise";
import { jsonFromFile } from "./stream";
import { shortAddressPreview } from "@ledgerhq/live-common/account/helpers";
import fs from "fs";

export const deviceOpt = {
name: "device",
alias: "d",
Expand Down Expand Up @@ -317,15 +317,8 @@ export function scan(arg: ScanCommonOpts): Observable<Account> {
});
const account: Account = {
type: "Account",
name:
currency.name +
" " +
(derivationMode || "legacy") +
" " +
shortAddressPreview(xpubOrAddress),
xpub: xpubOrAddress,
seedIdentifier: xpubOrAddress,
starred: true,
used: true,
swapHistory: [],
id,
Expand Down
1 change: 1 addition & 0 deletions apps/ledger-live-desktop/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
"@ledgerhq/live-network": "workspace:^",
"@ledgerhq/live-nft": "workspace:^",
"@ledgerhq/live-nft-react": "workspace:^",
"@ledgerhq/live-wallet": "workspace:^",
"@ledgerhq/logs": "workspace:^",
"@ledgerhq/react-ui": "workspace:^",
"@ledgerhq/types-cryptoassets": "workspace:^",
Expand Down
21 changes: 13 additions & 8 deletions apps/ledger-live-desktop/src/helpers/accountModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
*/
import { createDataModel, DataModel } from "@ledgerhq/live-common/DataModel";
import { fromAccountRaw, toAccountRaw } from "@ledgerhq/live-common/account/index";
import { Account, AccountRaw, Operation } from "@ledgerhq/types-live";
import { Account, AccountRaw, Operation, AccountUserData } from "@ledgerhq/types-live";
import { accountRawToAccountUserData } from "@ledgerhq/live-wallet/store";

/**
* @memberof models/account
Expand All @@ -15,7 +16,7 @@ export const opRetentionStategy =

const opRetentionFilter = opRetentionStategy(366, 500);

const accountModel: DataModel<AccountRaw, Account> = createDataModel({
const accountModel: DataModel<AccountRaw, [Account, AccountUserData]> = createDataModel({
migrations: [
// 2018-10-10: change of the account id format to include the derivationMode and seedIdentifier in Account
raw => {
Expand Down Expand Up @@ -78,11 +79,15 @@ const accountModel: DataModel<AccountRaw, Account> = createDataModel({
// ^- Each time a modification is brought to the model, add here a migration function here
],

decode: fromAccountRaw,
encode: (account: Account): AccountRaw =>
toAccountRaw({
...account,
operations: account.operations.filter(opRetentionFilter),
}),
decode: (raw: AccountRaw) => [fromAccountRaw(raw), accountRawToAccountUserData(raw)],
encode: ([account, userData]: [Account, AccountUserData]): AccountRaw =>
toAccountRaw(
{
...account,
operations: account.operations.filter(opRetentionFilter),
},
userData,
),
});

export default accountModel;
54 changes: 15 additions & 39 deletions apps/ledger-live-desktop/src/renderer/actions/accounts.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,24 @@
import { Dispatch } from "redux";
import { Account, SubAccount } from "@ledgerhq/types-live";
import { AccountComparator } from "@ledgerhq/live-common/account/index";
import { Account, AccountUserData } from "@ledgerhq/types-live";
import { AccountComparator } from "@ledgerhq/live-wallet/ordering";
import { getKey } from "~/renderer/storage";

export const replaceAccounts = (payload: Account[]) => ({
type: "DB:REPLACE_ACCOUNTS",
payload,
});

export const addAccount = (payload: Account) => ({
type: "DB:ADD_ACCOUNT",
payload,
});

export const removeAccount = (payload: Account) => ({
type: "DB:REMOVE_ACCOUNT",
payload,
});

export const setAccounts = (payload: Account[]) => ({
type: "SET_ACCOUNTS",
payload,
});
export const initAccounts = (data: [Account, AccountUserData][]) => {
const accounts = data.map(data => data[0]);
const accountsUserData = data.map(data => data[1]);
return {
type: "INIT_ACCOUNTS",
payload: {
accounts,
accountsUserData,
},
};
};

export const reorderAccounts = (comparator: AccountComparator) => (dispatch: Dispatch) =>
dispatch({
Expand All @@ -30,11 +27,8 @@ export const reorderAccounts = (comparator: AccountComparator) => (dispatch: Dis
});

export const fetchAccounts = () => async (dispatch: Dispatch) => {
const accounts = await getKey("app", "accounts", []);
return dispatch({
type: "SET_ACCOUNTS",
payload: accounts,
});
const data: [Account, AccountUserData][] = await getKey("app", "accounts", []);
return dispatch(initAccounts(data));
};

type UpdateAccountAction = {
Expand All @@ -61,24 +55,6 @@ export const updateAccount: UpdateAccount = payload => ({
},
});

export const toggleStarAction = (id: string, parentId?: string): UpdateAccountAction => {
return {
type: "DB:UPDATE_ACCOUNT",
payload: {
updater: (account: Account) => {
if (parentId && account.subAccounts) {
const subAccounts: SubAccount[] = account.subAccounts.map(sa =>
sa.id === id ? { ...sa, starred: !sa.starred } : sa,
);
return { ...account, subAccounts };
}
return { ...account, starred: !account.starred };
},
accountId: parentId || id,
},
};
};

export const cleanAccountsCache = () => ({ type: "DB:CLEAN_ACCOUNTS_CACHE" });
export const cleanFullNodeDisconnect = () => ({
type: "DB:CLEAN_FULLNODE_DISCONNECT",
Expand Down
14 changes: 7 additions & 7 deletions apps/ledger-live-desktop/src/renderer/actions/general.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@ import { createSelector } from "reselect";
// TODO make a generic way to implement this for each family
// eslint-disable-next-line no-restricted-imports
import { isAccountDelegating } from "@ledgerhq/live-common/families/tezos/bakers";
import {
flattenSortAccounts,
sortAccountsComparatorFromOrder,
FlattenAccountsOptions,
} from "@ledgerhq/live-common/account/index";
import { flattenSortAccounts } from "@ledgerhq/live-wallet/ordering";
import { reorderAccounts } from "~/renderer/actions/accounts";
import {
useCalculateCountervalueCallback as useCalculateCountervalueCallbackCommon,
Expand All @@ -26,6 +22,9 @@ import {
import { resolveTrackingPairs } from "@ledgerhq/live-countervalues/logic";
import { useExtraSessionTrackingPair } from "./deprecated/ondemand-countervalues";
import { useMarketPerformanceTrackingPairs } from "./marketperformance";
import { walletSelector } from "../reducers/wallet";
import { sortAccountsComparatorFromOrder } from "@ledgerhq/live-wallet/ordering";
import { FlattenAccountsOptions } from "@ledgerhq/live-common/account/index";

// provide redux states via custom hook wrapper

Expand All @@ -47,9 +46,10 @@ export function useCalculateCountervalueCallback() {
});
}
export function useSortAccountsComparator() {
const accounts = useSelector(getOrderAccounts);
const orderAccounts = useSelector(getOrderAccounts);
const calc = useCalculateCountervalueCallback();
return sortAccountsComparatorFromOrder(accounts, calc);
const walletState = useSelector(walletSelector);
return sortAccountsComparatorFromOrder(orderAccounts, walletState, calc);
}
export function useFlattenSortAccounts(options?: FlattenAccountsOptions) {
const accounts = useSelector(accountsSelector);
Expand Down
7 changes: 7 additions & 0 deletions apps/ledger-live-desktop/src/renderer/actions/wallet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { setAccountStarred } from "@ledgerhq/live-wallet/store";

export const toggleStarAction = (id: string, value: boolean) => {
const action = setAccountStarred(id, value);
action.type = "DB:" + action.type;
return action;
};
9 changes: 6 additions & 3 deletions apps/ledger-live-desktop/src/renderer/analytics/segment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import {
} from "~/renderer/reducers/settings";
import { State } from "~/renderer/reducers";
import { AccountLike, Feature, FeatureId, Features, idsToLanguage } from "@ledgerhq/types-live";
import { getAccountName } from "@ledgerhq/live-common/account/index";
import { accountsSelector } from "../reducers/accounts";
import {
GENESIS_PASS_COLLECTION_CONTRACT,
Expand All @@ -30,6 +29,7 @@ import createStore from "../createStore";
import { currentRouteNameRef, previousRouteNameRef } from "./screenRefs";
import { useCallback, useContext } from "react";
import { analyticsDrawerContext } from "../drawers/Provider";
import { getDefaultAccountName } from "@ledgerhq/live-wallet/accountName";
invariant(typeof window !== "undefined", "analytics/segment must be called on renderer thread");
// eslint-disable-next-line @typescript-eslint/no-var-requires
const os = require("os");
Expand Down Expand Up @@ -224,13 +224,16 @@ function sendTrack(event: string, properties: object | undefined | null) {
const confidentialityFilter = (properties?: Record<string, unknown> | null) => {
const { account, parentAccount } = properties || {};
const filterAccount = account
? { account: typeof account === "object" ? getAccountName(account as AccountLike) : account }
? {
account:
typeof account === "object" ? getDefaultAccountName(account as AccountLike) : account,
}
: {};
const filterParentAccount = parentAccount
? {
parentAccount:
typeof parentAccount === "object"
? getAccountName(parentAccount as AccountLike)
? getDefaultAccountName(parentAccount as AccountLike)
: parentAccount,
}
: {};
Expand Down
Loading

0 comments on commit 9fb494b

Please sign in to comment.