Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Currently extension supporty connect to OneKey via Trezor, but we dont have metric to log this when imported the accounts. #27296

Open
wants to merge 19 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
b0bee61
feat: log accountAdded and AccountFailed with `oneKey via trezor` as …
dawnseeker8 Sep 19, 2024
2142db3
feat: update the `OneKey via Trezor` log.
dawnseeker8 Sep 20, 2024
556084d
Merge branch 'develop' into feat/log-metric-for-oneKey-via-trezor
dawnseeker8 Sep 20, 2024
714110d
Merge remote-tracking branch 'origin/feat/log-metric-for-oneKey-via-t…
dawnseeker8 Sep 20, 2024
8fe7f39
feat: Fix a bug that original Trezor doesnt use label field, and mode…
dawnseeker8 Sep 20, 2024
9e9a0b1
feat: change the detection to use `minorVersion` to detect, also fix …
dawnseeker8 Sep 20, 2024
3667320
Merge branch 'develop' into feat/log-metric-for-oneKey-via-trezor
dawnseeker8 Sep 30, 2024
b42bf4b
Merge branch 'develop' into feat/log-metric-for-oneKey-via-trezor
dawnseeker8 Oct 1, 2024
be14d1f
Merge branch 'develop' into feat/log-metric-for-oneKey-via-trezor
dawnseeker8 Oct 1, 2024
bcc3966
chore: lint:fix
legobeat Oct 3, 2024
aa6e3bd
Merge branch 'develop' into feat/log-metric-for-oneKey-via-trezor
dawnseeker8 Oct 7, 2024
247f7bc
Merge branch 'develop' into feat/log-metric-for-oneKey-via-trezor
dawnseeker8 Oct 8, 2024
6297cf3
feat: Fix the lint error from `develop`branch.
dawnseeker8 Oct 8, 2024
73d8467
feat: add unit tests to cover actions.ts
dawnseeker8 Oct 8, 2024
0828900
feat: Fix the lint complaining about the missing await in try block.
dawnseeker8 Oct 8, 2024
c913ea5
feat: Try to improve the unit tests coverage.
dawnseeker8 Oct 8, 2024
f770b74
feat: fix a unit tests in actions.test.js
dawnseeker8 Oct 8, 2024
c63b6ee
feat: Fix a issue during OneKey testing.
dawnseeker8 Oct 8, 2024
02b8df2
Merge branch 'develop' into feat/log-metric-for-oneKey-via-trezor
dawnseeker8 Oct 8, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import {
export class TrezorOffscreenBridge implements TrezorBridge {
model: string | undefined;

minorVersion: number | undefined;

init(
settings: {
manifest: Manifest;
Expand All @@ -40,7 +42,8 @@ export class TrezorOffscreenBridge implements TrezorBridge {
msg.target === OffscreenCommunicationTarget.extension &&
msg.event === OffscreenCommunicationEvents.trezorDeviceConnect
) {
this.model = msg.payload;
this.model = msg.payload.model;
this.minorVersion = msg.payload.minorVersion;
}
});

Expand Down
26 changes: 25 additions & 1 deletion app/scripts/metamask-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -3357,6 +3357,7 @@ export default class MetamaskController extends EventEmitter {
connectHardware: this.connectHardware.bind(this),
forgetDevice: this.forgetDevice.bind(this),
checkHardwareStatus: this.checkHardwareStatus.bind(this),
getHardwareDeviceName: this.getHardwareDeviceName.bind(this),
unlockHardwareWalletAccount: this.unlockHardwareWalletAccount.bind(this),
attemptLedgerTransportCreation:
this.attemptLedgerTransportCreation.bind(this),
Expand Down Expand Up @@ -4694,15 +4695,38 @@ export default class MetamaskController extends EventEmitter {
/**
* get hardware account label
*
* @param name
* @param index
* @param hdPathDescription
* @returns string label
*/

getAccountLabel(name, index, hdPathDescription) {
return `${name[0].toUpperCase()}${name.slice(1)} ${
parseInt(index, 10) + 1
} ${hdPathDescription || ''}`.trim();
}

/**
* get hardware wallet Device name for metric logging in UI.
* Currently it only handle the special case for OneKeyDevice connect metamask via Trezor.
*
* @param deviceName - HardwareDeviceNames
* @param hdPath - string
* @returns {HardwareDeviceNames|*}
*/
async getHardwareDeviceName(deviceName, hdPath) {
if (deviceName === HardwareDeviceNames.trezor) {
const keyring = await this.getKeyringForDevice(deviceName, hdPath);
const { minorVersion } = keyring.bridge;
// OneKeyDevice can connect metamask via Trezor usb, and they use minorVersion 99 to differentiate oneKeyDevice and Trezor.
if (minorVersion && minorVersion === 99) {
return HardwareDeviceNames.oneKeyViaTrezor;
}
}

return deviceName;
}

/**
* Imports an account from a Trezor or Ledger device.
*
Expand Down
68 changes: 68 additions & 0 deletions app/scripts/metamask-controller.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -858,6 +858,74 @@ describe('MetaMaskController', () => {
);
});

describe('getHardwareDeviceName', () => {
it('should return the correct device name for Ledger', async () => {
const deviceName = 'ledger';
const hdPath = "m/44'/60'/0'/0/0";
const result = await metamaskController.getHardwareDeviceName(
deviceName,
hdPath,
);
expect(result).toBe('ledger');
});

it('should return the correct device name for Lattice', async () => {
const deviceName = 'lattice';
const hdPath = "m/44'/60'/0'/0/0";
const result = await metamaskController.getHardwareDeviceName(
deviceName,
hdPath,
);
expect(result).toBe('lattice');
});

it('should return the correct device name for Trezor', async () => {
const deviceName = 'trezor';
const hdPath = "m/44'/60'/0'/0";
jest
.spyOn(metamaskController, 'getKeyringForDevice')
.mockResolvedValue({
bridge: {
minorVersion: 1,
model: 'T',
},
});
const result = await metamaskController.getHardwareDeviceName(
deviceName,
hdPath,
);
expect(result).toBe('trezor');
});

it('should return undefined for unknown device name', async () => {
const deviceName = 'unknown';
const hdPath = "m/44'/60'/0'/0/0";
const result = await metamaskController.getHardwareDeviceName(
deviceName,
hdPath,
);
expect(result).toBe(deviceName);
});

it('should handle special case for OneKeyDevice via Trezor', async () => {
const deviceName = 'trezor';
const hdPath = "m/44'/60'/0'/0/0";
jest
.spyOn(metamaskController, 'getKeyringForDevice')
.mockResolvedValue({
bridge: {
model: 'T',
minorVersion: 99
},
});
const result = await metamaskController.getHardwareDeviceName(
deviceName,
hdPath,
);
expect(result).toBe('OneKey via Trezor');
});
});

describe('forgetDevice', () => {
it('should throw if it receives an unknown device name', async () => {
const result = metamaskController.forgetDevice(
Expand Down
5 changes: 4 additions & 1 deletion offscreen/scripts/trezor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@ export default function init() {
chrome.runtime.sendMessage({
target: OffscreenCommunicationTarget.extension,
event: OffscreenCommunicationEvents.trezorDeviceConnect,
payload: event.payload.features.model,
payload: {
model: event.payload.features.model,
minorVersion: event.payload.features.minor_version,
},
});
}
});
Expand Down
1 change: 1 addition & 0 deletions shared/constants/hardware-wallets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export enum HardwareKeyringNames {
export enum HardwareDeviceNames {
ledger = 'ledger',
trezor = 'trezor',
oneKeyViaTrezor = 'OneKey via Trezor',
lattice = 'lattice',
qr = 'QR Hardware',
}
Expand Down
17 changes: 13 additions & 4 deletions ui/pages/create-account/connect-hardware/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ import {
} from '../../../components/component-library';
import ZENDESK_URLS from '../../../helpers/constants/zendesk-url';
import { TextColor } from '../../../helpers/constants/design-system';
import SelectHardware from './select-hardware';
import { getHardwareDeviceName } from '../../../store/actions';
import AccountList from './account-list';
import SelectHardware from './select-hardware';

const U2F_ERROR = 'U2F';
const LEDGER_ERRORS_CODES = {
Expand Down Expand Up @@ -277,7 +278,7 @@ class ConnectHardwareForm extends Component {
});
};

onUnlockAccounts = (device, path) => {
onUnlockAccounts = async (device, path) => {
const { history, mostRecentOverviewPage, unlockHardwareWalletAccounts } =
this.props;
const { selectedAccounts } = this.state;
Expand All @@ -290,6 +291,10 @@ class ConnectHardwareForm extends Component {
MEW_PATH === path
? this.context.t('hardwareWalletLegacyDescription')
: '';

// process device type. specially handle trezor for oneKey device.
const metricDeviceName = await getHardwareDeviceName(device, path);

return unlockHardwareWalletAccounts(
selectedAccounts,
device,
Expand All @@ -302,7 +307,7 @@ class ConnectHardwareForm extends Component {
event: MetaMetricsEventName.AccountAdded,
properties: {
account_type: MetaMetricsEventAccountType.Hardware,
account_hardware_type: device,
account_hardware_type: metricDeviceName,
},
});
history.push(mostRecentOverviewPage);
Expand All @@ -313,7 +318,7 @@ class ConnectHardwareForm extends Component {
event: MetaMetricsEventName.AccountAddFailed,
properties: {
account_type: MetaMetricsEventAccountType.Hardware,
account_hardware_type: device,
account_hardware_type: metricDeviceName,
error: e.message,
},
});
Expand Down Expand Up @@ -459,6 +464,7 @@ const mapStateToProps = (state) => ({
rpcPrefs: getRpcPrefsForCurrentProvider(state),
accounts: getMetaMaskAccounts(state),
connectedAccounts: getMetaMaskAccountsConnected(state),
getHardwareDeviceName: getHardwareDeviceName(state),
defaultHdPaths: state.appState.defaultHdPaths,
mostRecentOverviewPage: getMostRecentOverviewPage(state),
ledgerTransportType: state.metamask.ledgerTransportType,
Expand All @@ -472,6 +478,9 @@ const mapDispatchToProps = (dispatch) => {
connectHardware: (deviceName, page, hdPath, t) => {
return dispatch(actions.connectHardware(deviceName, page, hdPath, t));
},
getHardwareDeviceName: (deviceName, hdPath) => {
return dispatch(actions.getHardwareDeviceName(deviceName, hdPath));
},
checkHardwareStatus: (deviceName, hdPath) => {
return dispatch(actions.checkHardwareStatus(deviceName, hdPath));
},
Expand Down
2 changes: 2 additions & 0 deletions ui/pages/create-account/connect-hardware/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ import ConnectHardwareForm from '.';

const mockConnectHardware = jest.fn();
const mockCheckHardwareStatus = jest.fn().mockResolvedValue(false);
const mockGetHardwareDeviceName = jest.fn().mockResolvedValue('ledger');

jest.mock('../../../store/actions', () => ({
connectHardware: () => mockConnectHardware,
checkHardwareStatus: () => mockCheckHardwareStatus,
getHardwareDeviceName: () => mockGetHardwareDeviceName,
}));

jest.mock('../../../selectors', () => ({
Expand Down
7 changes: 7 additions & 0 deletions ui/store/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,13 @@ export function checkHardwareStatus(
};
}

export const getHardwareDeviceName = (deviceName, hdPath) => {
return submitRequestToBackground('getHardwareDeviceName', [
deviceName,
hdPath,
]);
};

export function forgetDevice(
deviceName: HardwareDeviceNames,
): ThunkAction<void, MetaMaskReduxState, unknown, AnyAction> {
Expand Down