Skip to content

Commit

Permalink
feat: add batch pubkey path limit (#401)
Browse files Browse the repository at this point in the history
  • Loading branch information
ByteZhang1024 authored Jan 8, 2025
1 parent dbe656b commit e6cd696
Show file tree
Hide file tree
Showing 11 changed files with 62 additions and 48 deletions.
10 changes: 2 additions & 8 deletions packages/core/src/api/aptos/AptosGetAddress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { validateParams, validateResult } from '../helpers/paramsValidator';
import { AptosAddress, AptosGetAddressParams } from '../../types';
import { supportBatchPublicKey } from '../../utils/deviceFeaturesUtils';
import { hexToBytes } from '../helpers/hexUtils';
import { batchGetPublickeys } from '../helpers/batchGetPublickeys';

export default class AptosGetAddress extends BaseMethod<HardwareAptosGetAddress[]> {
hasBundle = false;
Expand Down Expand Up @@ -67,14 +68,7 @@ export default class AptosGetAddress extends BaseMethod<HardwareAptosGetAddress[
const supportsBatchPublicKey = supportBatchPublicKey(this.device?.features);
let responses: AptosAddress[] = [];
if (supportsBatchPublicKey) {
const publicKeyRes = await this.device.commands.typedCall(
'BatchGetPublickeys',
'EcdsaPublicKeys',
{
paths: this.params,
ecdsa_curve_name: 'ed25519',
}
);
const publicKeyRes = await batchGetPublickeys(this.device, this.params, 'ed25519', 637);

for (let i = 0; i < this.params.length; i++) {
const param = this.params[i];
Expand Down
6 changes: 2 additions & 4 deletions packages/core/src/api/aptos/AptosGetPublicKey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { serializedPath, validatePath } from '../helpers/pathUtils';
import { BaseMethod } from '../BaseMethod';
import { validateParams, validateResult } from '../helpers/paramsValidator';
import { AptosGetAddressParams, AptosPublicKey } from '../../types';
import { batchGetPublickeys } from '../helpers/batchGetPublickeys';

export default class AptosGetPublicKey extends BaseMethod<any> {
hasBundle = false;
Expand Down Expand Up @@ -45,10 +46,7 @@ export default class AptosGetPublicKey extends BaseMethod<any> {
}

async run() {
const res = await this.device.commands.typedCall('BatchGetPublickeys', 'EcdsaPublicKeys', {
paths: this.params,
ecdsa_curve_name: 'ed25519',
});
const res = await batchGetPublickeys(this.device, this.params, 'ed25519', 637);

const responses: AptosPublicKey[] = res.message.public_keys.map(
(publicKey: string, index: number) => ({
Expand Down
11 changes: 2 additions & 9 deletions packages/core/src/api/benfen/BenfenGetAddress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { UI_REQUEST } from '../../constants/ui-request';
import { hex2BfcAddress, publicKeyToAddress } from './normalize';
import { BenfenAddress, BenfenGetAddressParams } from '../../types';
import { supportBatchPublicKey } from '../../utils/deviceFeaturesUtils';
import { batchGetPublickeys } from '../helpers/batchGetPublickeys';

export default class BenfenGetAddress extends BaseMethod<HardwareBenfenGetAddress[]> {
hasBundle = false;
Expand Down Expand Up @@ -62,15 +63,7 @@ export default class BenfenGetAddress extends BaseMethod<HardwareBenfenGetAddres
let responses: BenfenAddress[] = [];

if (supportsBatchPublicKey) {
const publicKeyRes = await this.device.commands.typedCall(
'BatchGetPublickeys',
'EcdsaPublicKeys',
{
paths: this.params,
ecdsa_curve_name: 'ed25519',
}
);

const publicKeyRes = await batchGetPublickeys(this.device, this.params, 'ed25519', 728);
for (let i = 0; i < this.params.length; i++) {
const param = this.params[i];
const publicKey = publicKeyRes.message.public_keys[i];
Expand Down
6 changes: 2 additions & 4 deletions packages/core/src/api/benfen/BenfenGetPublicKey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { validateParams, validateResult } from '../helpers/paramsValidator';
import { serializedPath, validatePath } from '../helpers/pathUtils';
import { UI_REQUEST } from '../../constants/ui-request';
import { BenfenPublicKey, BenfenGetPublicKeyParams } from '../../types';
import { batchGetPublickeys } from '../helpers/batchGetPublickeys';

export default class BenfenGetPublicKey extends BaseMethod<any> {
hasBundle = false;
Expand Down Expand Up @@ -48,10 +49,7 @@ export default class BenfenGetPublicKey extends BaseMethod<any> {
}

async run() {
const res = await this.device.commands.typedCall('BatchGetPublickeys', 'EcdsaPublicKeys', {
paths: this.params,
ecdsa_curve_name: 'ed25519',
});
const res = await batchGetPublickeys(this.device, this.params, 'ed25519', 728);

const responses: BenfenPublicKey[] = res.message.public_keys.map(
(publicKey: string, index: number) => ({
Expand Down
7 changes: 2 additions & 5 deletions packages/core/src/api/cosmos/CosmosGetPublicKey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { serializedPath, validatePath } from '../helpers/pathUtils';
import { BaseMethod } from '../BaseMethod';
import { validateParams, validateResult } from '../helpers/paramsValidator';
import { CosmosAddress, CosmosGetPublicKeyParams } from '../../types';
import { batchGetPublickeys } from '../helpers/batchGetPublickeys';

export default class CosmosGetPublicKey extends BaseMethod<any> {
hasBundle = false;
Expand Down Expand Up @@ -59,11 +60,7 @@ export default class CosmosGetPublicKey extends BaseMethod<any> {
}

async run() {
const res = await this.device.commands.typedCall('BatchGetPublickeys', 'EcdsaPublicKeys', {
paths: this.params,
ecdsa_curve_name: this.params[0].curve,
});

const res = await batchGetPublickeys(this.device, this.params, this.params[0].curve, 118);
const responses: CosmosAddress[] = res.message.public_keys.map(
(publicKey: string, index: number) => ({
path: serializedPath((this.params as unknown as any[])[index].address_n),
Expand Down
33 changes: 33 additions & 0 deletions packages/core/src/api/helpers/batchGetPublickeys.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Path } from '@onekeyfe/hd-transport';

import { TypedError, HardwareErrorCode } from '@onekeyfe/hd-shared';
import { Device } from '../../device/Device';
import { supportBatchPublicKey } from '../../utils/deviceFeaturesUtils';
import { isEqualBip44CoinType } from './pathUtils';

export function batchGetPublickeys(
device: Device,
paths: Path[],
ecdsaCurveName: string,
coinType: number
) {
const existsPathNotValid = paths.find(p => p.address_n.length < 3);
if (existsPathNotValid) {
throw TypedError(HardwareErrorCode.ForbiddenKeyPath, 'Path length must be greater than 3');
}

const supportsBatchPublicKey = supportBatchPublicKey(device.features);
if (!supportsBatchPublicKey) {
throw TypedError(HardwareErrorCode.DeviceNotSupportMethod);
}

const existsPathNotEqualCoinType = paths.find(p => !isEqualBip44CoinType(p.address_n, coinType));
if (existsPathNotEqualCoinType) {
throw TypedError(HardwareErrorCode.ForbiddenKeyPath);
}

return device.commands.typedCall('BatchGetPublickeys', 'EcdsaPublicKeys', {
paths,
ecdsa_curve_name: ecdsaCurveName,
});
}
6 changes: 6 additions & 0 deletions packages/core/src/api/helpers/pathUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ export const getHDPath = (path: string): Array<number> => {
});
};

export const isEqualBip44CoinType = (path: Array<number>, coinType: number): boolean =>
isBip44Path(path) && path[1] === toHardened(coinType);

export const isBip44Path = (path: Array<number>): boolean =>
Array.isArray(path) && path[0] === toHardened(44);

export const isMultisigPath = (path: Array<number>): boolean =>
Array.isArray(path) && path[0] === toHardened(48);

Expand Down
12 changes: 3 additions & 9 deletions packages/core/src/api/sui/SuiGetAddress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { validateParams, validateResult } from '../helpers/paramsValidator';
import { SuiAddress, SuiGetAddressParams } from '../../types';
import { supportBatchPublicKey } from '../../utils/deviceFeaturesUtils';
import { publicKeyToAddress } from './normalize';
import { batchGetPublickeys } from '../helpers/batchGetPublickeys';

export default class SuiGetAddress extends BaseMethod<HardwareSuiGetAddress[]> {
hasBundle = false;
Expand Down Expand Up @@ -61,18 +62,11 @@ export default class SuiGetAddress extends BaseMethod<HardwareSuiGetAddress[]> {
const supportsBatchPublicKey = supportBatchPublicKey(this.device?.features);
let responses: SuiAddress[] = [];
if (supportsBatchPublicKey) {
const publicKeyRes = await this.device.commands.typedCall(
'BatchGetPublickeys',
'EcdsaPublicKeys',
{
paths: this.params,
ecdsa_curve_name: 'ed25519',
}
);
const publicKeyRes = await batchGetPublickeys(this.device, this.params, 'ed25519', 784);
for (let i = 0; i < this.params.length; i++) {
const param = this.params[i];
const publicKey = publicKeyRes.message.public_keys[i];
let address: string;
let address: string | undefined;

if (this.shouldConfirm) {
const addressRes = await this.device.commands.typedCall(
Expand Down
7 changes: 2 additions & 5 deletions packages/core/src/api/sui/SuiGetPublicKey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { serializedPath, validatePath } from '../helpers/pathUtils';
import { BaseMethod } from '../BaseMethod';
import { validateParams, validateResult } from '../helpers/paramsValidator';
import { SuiGetAddressParams, SuiPublicKey } from '../../types';
import { batchGetPublickeys } from '../helpers/batchGetPublickeys';

export default class SuiGetPublicKey extends BaseMethod<any> {
hasBundle = false;
Expand Down Expand Up @@ -48,11 +49,7 @@ export default class SuiGetPublicKey extends BaseMethod<any> {
}

async run() {
const res = await this.device.commands.typedCall('BatchGetPublickeys', 'EcdsaPublicKeys', {
paths: this.params,
ecdsa_curve_name: 'ed25519',
});

const res = await batchGetPublickeys(this.device, this.params, 'ed25519', 784);
const responses: SuiPublicKey[] = res.message.public_keys.map(
(publicKey: string, index: number) => ({
path: serializedPath((this.params as unknown as any[])[index].address_n),
Expand Down
6 changes: 2 additions & 4 deletions packages/core/src/api/xrp/XrpGetAddress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { supportBatchPublicKey } from '../../utils/deviceFeaturesUtils';
import { BaseMethod } from '../BaseMethod';
import { validateParams, validateResult } from '../helpers/paramsValidator';
import { serializedPath, validatePath } from '../helpers/pathUtils';
import { batchGetPublickeys } from '../helpers/batchGetPublickeys';

export default class XrpGetAddress extends BaseMethod<
{
Expand Down Expand Up @@ -57,10 +58,7 @@ export default class XrpGetAddress extends BaseMethod<

async run() {
if (this.hasBundle && supportBatchPublicKey(this.device?.features) && !this.shouldConfirm) {
const res = await this.device.commands.typedCall('BatchGetPublickeys', 'EcdsaPublicKeys', {
paths: this.params,
ecdsa_curve_name: 'secp256k1',
});
const res = await batchGetPublickeys(this.device, this.params, 'secp256k1', 144);
const result = res.message.public_keys.map((publicKey: string, index: number) => ({
path: serializedPath((this.params as unknown as any[])[index].address_n),
publicKey,
Expand Down
6 changes: 6 additions & 0 deletions packages/shared/src/HardwareError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,11 @@ export const HardwareErrorCode = {
*/
DeviceNotSupportMethod: 415,

/**
* Forbidden key path
*/
ForbiddenKeyPath: 416,

/**
* Netword request error
*/
Expand Down Expand Up @@ -435,6 +440,7 @@ export const HardwareErrorCodeMessage: HardwareErrorCodeMessageMapping = {
[HardwareErrorCode.UseDesktopToUpdateFirmware]:
'Please use OneKey desktop client to update the firmware',
[HardwareErrorCode.DeviceNotSupportMethod]: 'Device not support this method',
[HardwareErrorCode.ForbiddenKeyPath]: 'Forbidden key path',

/**
* Network Errors
Expand Down

0 comments on commit e6cd696

Please sign in to comment.