Skip to content

Commit fd95351

Browse files
authored
refactor: new X/P chains account model (#499)
1 parent 1b1aa30 commit fd95351

File tree

101 files changed

+2502
-1162
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

101 files changed

+2502
-1162
lines changed

apps/legacy/package.json

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,28 +15,28 @@
1515
"typecheck": "yarn tsc --skipLibCheck --noEmit"
1616
},
1717
"dependencies": {
18-
"@avalabs/avalanche-module": "2.2.1",
18+
"@avalabs/avalanche-module": "3.0.0",
1919
"@avalabs/avalanchejs": "5.1.0-alpha.2",
20-
"@avalabs/bitcoin-module": "2.2.1",
20+
"@avalabs/bitcoin-module": "3.0.0",
2121
"@avalabs/bridge-unified": "4.3.0",
22-
"@avalabs/core-bridge-sdk": "3.1.0-alpha.67",
23-
"@avalabs/core-chains-sdk": "3.1.0-alpha.67",
24-
"@avalabs/core-coingecko-sdk": "3.1.0-alpha.67",
25-
"@avalabs/core-covalent-sdk": "3.1.0-alpha.67",
26-
"@avalabs/core-etherscan-sdk": "3.1.0-alpha.67",
27-
"@avalabs/core-gasless-sdk": "3.1.0-alpha.67",
22+
"@avalabs/core-bridge-sdk": "3.1.0-alpha.69",
23+
"@avalabs/core-chains-sdk": "3.1.0-alpha.69",
24+
"@avalabs/core-coingecko-sdk": "3.1.0-alpha.69",
25+
"@avalabs/core-covalent-sdk": "3.1.0-alpha.69",
26+
"@avalabs/core-etherscan-sdk": "3.1.0-alpha.69",
27+
"@avalabs/core-gasless-sdk": "3.1.0-alpha.69",
2828
"@avalabs/core-k2-components": "4.18.0-alpha.53",
29-
"@avalabs/core-snowtrace-sdk": "3.1.0-alpha.67",
30-
"@avalabs/core-token-prices-sdk": "3.1.0-alpha.67",
31-
"@avalabs/core-utils-sdk": "3.1.0-alpha.67",
32-
"@avalabs/core-wallets-sdk": "3.1.0-alpha.67",
33-
"@avalabs/evm-module": "2.2.1",
34-
"@avalabs/glacier-sdk": "3.1.0-alpha.67",
35-
"@avalabs/hvm-module": "2.2.1",
29+
"@avalabs/core-snowtrace-sdk": "3.1.0-alpha.69",
30+
"@avalabs/core-token-prices-sdk": "3.1.0-alpha.69",
31+
"@avalabs/core-utils-sdk": "3.1.0-alpha.69",
32+
"@avalabs/core-wallets-sdk": "3.1.0-alpha.69",
33+
"@avalabs/evm-module": "3.0.0",
34+
"@avalabs/glacier-sdk": "3.1.0-alpha.69",
35+
"@avalabs/hvm-module": "3.0.0",
3636
"@avalabs/hw-app-avalanche": "1.1.1",
37-
"@avalabs/svm-module": "2.2.1",
38-
"@avalabs/types": "3.1.0-alpha.67",
39-
"@avalabs/vm-module-types": "2.2.1",
37+
"@avalabs/svm-module": "3.0.0",
38+
"@avalabs/types": "3.1.0-alpha.69",
39+
"@avalabs/vm-module-types": "3.0.0",
4040
"@blockaid/client": "0.10.0",
4141
"@coinbase/cbpay-js": "1.6.0",
4242
"@core/common": "workspace:*",

apps/legacy/src/components/keystone/KeystoneConnector.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,8 @@ export function KeystoneConnector({ onSuccess }: KeystoneConnectorProps) {
9090
const getXPublicKey = useCallback(async () => {
9191
try {
9292
const mfp = await getMasterFingerprint();
93-
const xpubValue = await getExtendedPublicKey();
94-
const xpubXPValue = await getExtendedPublicKey(ChainIDAlias.X);
93+
const xpubValue = await getExtendedPublicKey(ChainIDAlias.C, 0);
94+
const xpubXPValue = await getExtendedPublicKey(ChainIDAlias.X, 0);
9595
capture('OnboardingKeystone3Connected');
9696
onSuccess({
9797
xpub: xpubValue,

apps/next/package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@
1717
},
1818
"dependencies": {
1919
"@avalabs/avalanchejs": "5.1.0-alpha.2",
20-
"@avalabs/core-chains-sdk": "3.1.0-alpha.67",
21-
"@avalabs/core-utils-sdk": "3.1.0-alpha.67",
22-
"@avalabs/core-wallets-sdk": "3.1.0-alpha.67",
20+
"@avalabs/core-chains-sdk": "3.1.0-alpha.69",
21+
"@avalabs/core-utils-sdk": "3.1.0-alpha.69",
22+
"@avalabs/core-wallets-sdk": "3.1.0-alpha.69",
2323
"@avalabs/k2-alpine": "1.235.0",
24-
"@avalabs/types": "3.1.0-alpha.67",
25-
"@avalabs/vm-module-types": "2.2.1",
24+
"@avalabs/types": "3.1.0-alpha.69",
25+
"@avalabs/vm-module-types": "3.0.0",
2626
"@core/common": "workspace:*",
2727
"@core/messaging": "workspace:*",
2828
"@core/service-worker": "workspace:*",

apps/next/src/components/ConnectLedger/ConnectAvalanche.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ export const ConnectAvalanche: FC<ConnectionStepProps> = ({
6969
onStatusChange={setStatus}
7070
setDerivationPathSpec={setDerivationPathSpec}
7171
derivationPathSpec={derivationPathSpec}
72-
numberOfKeys={3}
72+
numberOfKeys={1}
7373
/>
7474
</FullscreenModalContent>
7575
<FullscreenModalActions>

apps/next/src/components/ConnectLedger/LedgerConnector/hooks/useLedgerPublicKeyFetcher/useLedgerBasePublicKeyFetcher.ts

Lines changed: 46 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,18 @@ import {
33
DerivationPath,
44
getAddressPublicKeyFromXPub,
55
} from '@avalabs/core-wallets-sdk';
6-
import { VM } from '@avalabs/avalanchejs';
76

87
import {
98
LedgerAppType,
109
REQUIRED_LEDGER_VERSION,
1110
useLedgerContext,
1211
useDuplicatedWalletChecker,
1312
} from '@core/ui';
13+
import { EVM_BASE_DERIVATION_PATH, SecretType } from '@core/types';
1414
import {
15-
AddressPublicKeyJson,
16-
AVALANCHE_BASE_DERIVATION_PATH,
17-
EVM_BASE_DERIVATION_PATH,
18-
SecretType,
19-
} from '@core/types';
20-
import { isLedgerVersionCompatible } from '@core/common';
15+
getAvalancheExtendedKeyPath,
16+
isLedgerVersionCompatible,
17+
} from '@core/common';
2118

2219
import {
2320
DerivationStatus,
@@ -32,6 +29,10 @@ import { buildAddressPublicKey, buildExtendedPublicKey } from '../../util';
3229
export const useLedgerBasePublicKeyFetcher: UseLedgerPublicKeyFetcher = (
3330
derivationPathSpec,
3431
) => {
32+
if (!derivationPathSpec) {
33+
throw new Error('Derivation path spec is required');
34+
}
35+
3536
const {
3637
appType,
3738
avaxAppVersion,
@@ -40,109 +41,78 @@ export const useLedgerBasePublicKeyFetcher: UseLedgerPublicKeyFetcher = (
4041
wasTransportAttempted,
4142
initLedgerTransport,
4243
getExtendedPublicKey,
43-
getPublicKey,
4444
} = useLedgerContext();
4545
const checkIfWalletExists = useDuplicatedWalletChecker();
4646

4747
const [error, setError] = useState<ErrorType>();
4848
const [status, setStatus] = useState<DerivationStatus>('waiting');
4949

50-
const getPublicKeyFromLedger = useCallback(
51-
async (accountIndex: number, vm: VM): Promise<AddressPublicKeyJson> => {
52-
const publicKey = await getPublicKey(
53-
accountIndex,
54-
DerivationPath.LedgerLive,
55-
vm,
56-
);
57-
58-
return buildAddressPublicKey(publicKey, vm, accountIndex, 'secp256k1');
59-
},
60-
[getPublicKey],
61-
);
62-
63-
// Used with LedgerLive derivation path, as with such we cannot use the extended public keys
64-
const getKeysDirectlyFromLedger = useCallback(
50+
const getExtendedPublicKeys = useCallback(
6551
async (indexes: number[]) => {
66-
const keys: PublicKey[] = [];
52+
const xpExtendedPublicKeys: { index: number; key: string }[] = [];
6753

68-
// We cannot send multiple requests to the ledger at once, so we need to do one at a time
6954
for (const index of indexes) {
70-
const evmKey = await getPublicKeyFromLedger(index, 'EVM');
71-
keys.push({
55+
xpExtendedPublicKeys.push({
7256
index,
73-
vm: 'EVM',
74-
key: evmKey,
75-
});
76-
77-
const xpKey = await getPublicKeyFromLedger(index, 'AVM');
78-
keys.push({
79-
index,
80-
vm: 'AVM',
81-
key: xpKey,
57+
key: await getExtendedPublicKey(getAvalancheExtendedKeyPath(index)),
8258
});
8359
}
8460

8561
return {
86-
addressPublicKeys: keys,
62+
evm: await getExtendedPublicKey(EVM_BASE_DERIVATION_PATH),
63+
xp: xpExtendedPublicKeys,
8764
};
8865
},
89-
[getPublicKeyFromLedger],
66+
[getExtendedPublicKey],
9067
);
9168

92-
// Used with BIP44 derivation path, as it's way faster to get the keys from the extended public keys
93-
// and derive address public keys from them than to query the device many times more.
94-
//
95-
// Having the extended public keys also allows us to derive further addresses without connecting the device
96-
// later on.
97-
const getKeysFromExtendedPublicKeys = useCallback(
69+
const getPublicKeys = useCallback(
9870
async (indexes: number[]) => {
99-
const evmExtendedPublicKey = await getExtendedPublicKey(
100-
EVM_BASE_DERIVATION_PATH,
101-
);
102-
const xpExtendedPublicKey = await getExtendedPublicKey(
103-
AVALANCHE_BASE_DERIVATION_PATH,
104-
);
71+
const publicKeys: PublicKey[] = [];
72+
const { evm, xp: xpExtendedKeys } = await getExtendedPublicKeys(indexes);
10573

106-
const keys: PublicKey[] = [];
107-
108-
// We cannot send multiple requests to the ledger at once, so we need to do one at a time
10974
for (const index of indexes) {
110-
const evmKey = await getAddressPublicKeyFromXPub(
111-
evmExtendedPublicKey,
112-
index,
113-
);
114-
keys.push({
75+
const evmKey = await getAddressPublicKeyFromXPub(evm, index);
76+
publicKeys.push({
11577
index,
11678
vm: 'EVM',
117-
key: buildAddressPublicKey(evmKey, 'EVM', index, 'secp256k1'),
79+
key: buildAddressPublicKey(
80+
evmKey,
81+
'EVM',
82+
index,
83+
'secp256k1',
84+
derivationPathSpec,
85+
),
11886
});
87+
}
11988

120-
const xpKey = await getAddressPublicKeyFromXPub(
121-
xpExtendedPublicKey,
122-
index,
123-
);
124-
keys.push({
89+
for (const { key: xpubXP, index } of xpExtendedKeys) {
90+
const addressPublicKey = await getAddressPublicKeyFromXPub(xpubXP, 0);
91+
92+
publicKeys.push({
12593
index,
12694
vm: 'AVM',
127-
key: buildAddressPublicKey(xpKey, 'AVM', index, 'secp256k1'),
95+
key: buildAddressPublicKey(
96+
addressPublicKey,
97+
'AVM',
98+
index,
99+
'secp256k1',
100+
derivationPathSpec,
101+
),
128102
});
129103
}
130104

131105
return {
132106
extendedPublicKeys: [
133-
buildExtendedPublicKey(
134-
evmExtendedPublicKey,
135-
EVM_BASE_DERIVATION_PATH,
136-
),
137-
buildExtendedPublicKey(
138-
xpExtendedPublicKey,
139-
AVALANCHE_BASE_DERIVATION_PATH,
107+
buildExtendedPublicKey(evm, EVM_BASE_DERIVATION_PATH),
108+
...xpExtendedKeys.map(({ key, index }) =>
109+
buildExtendedPublicKey(key, getAvalancheExtendedKeyPath(index)),
140110
),
141111
],
142-
addressPublicKeys: keys,
112+
addressPublicKeys: publicKeys,
143113
};
144114
},
145-
[getExtendedPublicKey],
115+
[getExtendedPublicKeys, derivationPathSpec],
146116
);
147117

148118
const assertUniqueWallet = useCallback(
@@ -177,10 +147,7 @@ export const useLedgerBasePublicKeyFetcher: UseLedgerPublicKeyFetcher = (
177147
const retrieveKeys = useCallback(
178148
async (indexes: number[]) => {
179149
try {
180-
const isLedgerLive = derivationPathSpec === DerivationPath.LedgerLive;
181-
const keys = isLedgerLive
182-
? await getKeysDirectlyFromLedger(indexes)
183-
: await getKeysFromExtendedPublicKeys(indexes);
150+
const keys = await getPublicKeys(indexes);
184151

185152
await assertUniqueWallet(keys);
186153

@@ -191,13 +158,7 @@ export const useLedgerBasePublicKeyFetcher: UseLedgerPublicKeyFetcher = (
191158
throw err;
192159
}
193160
},
194-
[
195-
derivationPathSpec,
196-
getKeysDirectlyFromLedger,
197-
getKeysFromExtendedPublicKeys,
198-
popDeviceSelection,
199-
assertUniqueWallet,
200-
],
161+
[getPublicKeys, popDeviceSelection, assertUniqueWallet],
201162
);
202163

203164
// Attempt to automatically connect as soon as we establish the transport.

apps/next/src/components/ConnectLedger/LedgerConnector/hooks/useLedgerPublicKeyFetcher/useLedgerSolanaPublicKeyFetcher.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,13 @@ export const useLedgerSolanaPublicKeyFetcher: UseLedgerPublicKeyFetcher =
3535
'SVM',
3636
);
3737

38-
return buildAddressPublicKey(publicKey, 'SVM', accountIndex, 'ed25519');
38+
return buildAddressPublicKey(
39+
publicKey,
40+
'SVM',
41+
accountIndex,
42+
'ed25519',
43+
DerivationPath.LedgerLive,
44+
);
3945
},
4046
[getPublicKey],
4147
);

apps/next/src/components/ConnectLedger/LedgerConnector/util/buildAddressPublicKey.ts

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,21 @@ import { hex } from '@scure/base';
22
import {
33
DerivationPath,
44
getAddressDerivationPath,
5-
getSolanaDerivationPath,
65
} from '@avalabs/core-wallets-sdk';
76
import { VM } from '@avalabs/avalanchejs';
87
import { AddressPublicKeyJson, Curve } from '@core/types';
98

10-
export const buildAddressPublicKey = (
9+
export function buildAddressPublicKey(
1110
key: Buffer,
1211
vm: VM | 'SVM',
1312
accountIndex: number,
1413
curve: Curve,
15-
): AddressPublicKeyJson => ({
16-
curve,
17-
derivationPath:
18-
vm === 'SVM'
19-
? getSolanaDerivationPath(accountIndex)
20-
: getAddressDerivationPath(accountIndex, DerivationPath.LedgerLive, vm),
21-
type: 'address-pubkey',
22-
key: hex.encode(Uint8Array.from(key)),
23-
});
14+
pathSpec: DerivationPath,
15+
): AddressPublicKeyJson {
16+
return {
17+
curve,
18+
derivationPath: getAddressDerivationPath(accountIndex, vm, { pathSpec }),
19+
type: 'address-pubkey',
20+
key: hex.encode(Uint8Array.from(key)),
21+
};
22+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { useTranslation } from 'react-i18next';
2+
import { FiAlertCircle } from 'react-icons/fi';
3+
import { FC, useEffect, useState } from 'react';
4+
import { Stack, Typography, useTheme } from '@avalabs/k2-alpine';
5+
6+
import { useIsIncorrectDevice, useLedgerContext } from '@core/ui';
7+
8+
import { Page } from '@/components/Page';
9+
import { SlideUpDialog } from '@/components/Dialog';
10+
11+
export const LedgerIncorrectDevice: FC = () => {
12+
const { t } = useTranslation();
13+
const [isDialogOpen, setIsDialogOpen] = useState(false);
14+
const { closeCurrentApp } = useLedgerContext();
15+
const isIncorrectDevice = useIsIncorrectDevice();
16+
const theme = useTheme();
17+
18+
useEffect(() => {
19+
if (isIncorrectDevice) {
20+
setIsDialogOpen(true);
21+
closeCurrentApp();
22+
}
23+
}, [isIncorrectDevice, closeCurrentApp]);
24+
25+
return (
26+
<SlideUpDialog open={isDialogOpen}>
27+
<Page
28+
title={t('Incorrect Ledger')}
29+
withBackButton={false}
30+
withViewSwitcher={false}
31+
>
32+
<Typography variant="body3">
33+
{t(
34+
'This Ledger was not used to create this wallet. Please connect the original Ledger device to continue.',
35+
)}
36+
</Typography>
37+
<Stack sx={{ mt: '48px', mb: '16px' }}>
38+
<FiAlertCircle color={theme.palette.error.main} />
39+
</Stack>
40+
</Page>
41+
</SlideUpDialog>
42+
);
43+
};
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './LedgerIncorrectDevice';
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export * from './LedgerRegisterBtcWalletPolicy';
2+
export * from './LedgerIncorrectDevice';

0 commit comments

Comments
 (0)