Skip to content

Commit

Permalink
Merge branch 'development' of github.com:LiskHQ/lisk-desktop into dev…
Browse files Browse the repository at this point in the history
…elopment
  • Loading branch information
ikem-legend committed May 16, 2024
2 parents 454678e + b51efb7 commit 36fcb58
Show file tree
Hide file tree
Showing 14 changed files with 421 additions and 271 deletions.
2 changes: 1 addition & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"PRODUCTION": true,
"LISK_DOMAIN": true,
"REACT_APP_DEFAULT_NETWORK": true,
"REACT_APP_MAPBOX_ACCESS_TOKEN": true,
"REACT_APP_MAPBOX_ACCESS_TOKEN": true
},
"env": {
"es2020": true,
Expand Down
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@ app/app.js
blockchain_explorer.db.gz
reports
.history
.env.*
yarn-error.log
*.tgz

## Local environment files
.env.*
!.env.example

## Commercial fonts
setup/react/assets/fonts/basierCircle/
setup/react/assets/fonts/gilroy/
Expand Down
2 changes: 1 addition & 1 deletion Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ pipeline {
ansiColor('xterm')
}
parameters {
string(name: 'CORE_VERSION', defaultValue: '4.0.2')
string(name: 'CORE_VERSION', defaultValue: '4.0.5')
string(name: 'SERVICE_BRANCH_NAME', defaultValue: 'development')
}
stages {
Expand Down
2 changes: 1 addition & 1 deletion app/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "lisk-desktop",
"version": "3.0.1",
"version": "3.0.2-alpha.0",
"productName": "Lisk",
"description": "Lisk",
"main": "./build/main.js",
Expand Down
9 changes: 9 additions & 0 deletions app/src/ipc.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const { contextBridge, ipcRenderer } = require('electron');
const REQUEST = 'REQUEST';
const RESPONSE = 'RESPONSE';
const GET_SIGNED_MESSAGE = 'GET_SIGNED_MESSAGE';
const GET_SIGNED_RAW_MESSAGE = 'GET_SIGNED_RAW_MESSAGE';
const GET_SIGNED_TRANSACTION = 'GET_SIGNED_TRANSACTION';
const GET_PUB_KEY = 'GET_PUB_KEY';
const GET_MULTIPLE_ADDRESSES = 'GET_MULTIPLE_ADDRESSES';
Expand Down Expand Up @@ -61,6 +62,9 @@ contextBridge.exposeInMainWorld('ipc', {
[`${GET_SIGNED_MESSAGE}.${REQUEST}`]: (title) => {
ipcRenderer.send(`${GET_SIGNED_MESSAGE}.${REQUEST}`, title);
},
[`${GET_SIGNED_RAW_MESSAGE}.${REQUEST}`]: (title) => {
ipcRenderer.send(`${GET_SIGNED_RAW_MESSAGE}.${REQUEST}`, title);
},
[`${GET_CONNECTED_DEVICES}.${RESPONSE}`]: (func) => {
ipcRenderer.once(`${GET_CONNECTED_DEVICES}.${RESPONSE}`, (event, ...args) => {
func(event, ...args);
Expand Down Expand Up @@ -91,6 +95,11 @@ contextBridge.exposeInMainWorld('ipc', {
func(event, ...args);
});
},
[`${GET_SIGNED_RAW_MESSAGE}.${RESPONSE}`]: (func) => {
ipcRenderer.once(`${GET_SIGNED_RAW_MESSAGE}.${RESPONSE}`, (event, ...args) => {
func(event, ...args);
});
},
[LEDGER_HW_HID_EVENT]: (func) => {
ipcRenderer.on(LEDGER_HW_HID_EVENT, (event, ...args) => {
func(event, ...args);
Expand Down
1 change: 1 addition & 0 deletions libs/hardwareWallet/ledger/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export const REQUEST = 'REQUEST';
export const LEDGER_HW_HID_EVENT = 'LEDGER_HW_HID_EVENT';
export const LEDGER_HW_IPC_CHANNELS = {
GET_SIGNED_MESSAGE: 'GET_SIGNED_MESSAGE',
GET_SIGNED_RAW_MESSAGE: 'GET_SIGNED_RAW_MESSAGE',
GET_SIGNED_TRANSACTION: 'GET_SIGNED_TRANSACTION',
GET_PUB_KEY: 'GET_PUB_KEY',
GET_MULTIPLE_ADDRESSES: 'GET_MULTIPLE_ADDRESSES',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const {
GET_PUB_KEY,
GET_MULTIPLE_ADDRESSES,
GET_SIGNED_MESSAGE,
GET_SIGNED_RAW_MESSAGE,
} = LEDGER_HW_IPC_CHANNELS;

function sleep(ms) {
Expand All @@ -34,6 +35,16 @@ export const getSignedMessage = async (devicePath, accountIndex, unsignedMessage
return signedMessage;
};

export const getSignedRawMessage = async (devicePath, accountIndex, unsignedMessage) => {
const signedRawMessage = await executeIPCCommand(GET_SIGNED_RAW_MESSAGE, {
devicePath,
accountIndex,
unsignedMessage,
});

return signedRawMessage;
};

export const getPubKey = async (devicePath, accountIndex, showOnDevice) => {
const pubKey = await executeIPCCommand(GET_PUB_KEY, {
devicePath,
Expand Down
8 changes: 8 additions & 0 deletions libs/hardwareWallet/ledger/ledgerLiskAppIPCChannel/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ import {
getPubKey,
getConnectedDevices,
getSignedMessage,
getSignedRawMessage,
getSignedTransaction,
getMultipleAddresses,
} from './serverLedgerHWCommunication';

const {
GET_CONNECTED_DEVICES,
GET_SIGNED_MESSAGE,
GET_SIGNED_RAW_MESSAGE,
GET_PUB_KEY,
GET_MULTIPLE_ADDRESSES,
GET_SIGNED_TRANSACTION,
Expand All @@ -36,6 +38,12 @@ export const ledgerLiskAppIPCChannel = () => {
return result;
});

createIpcMainChannel(GET_SIGNED_RAW_MESSAGE, async (data) => {
const id = `${GET_SIGNED_RAW_MESSAGE}-${Date.now()}`;
const result = await getSequentiallyQueuedData(myq, id, () => getSignedRawMessage(data));
return result;
});

createIpcMainChannel(GET_PUB_KEY, async (data) => {
const id = `${GET_PUB_KEY}-${Date.now()}`;
const result = await getSequentiallyQueuedData(myq, id, () => getPubKey(data));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ const isHexString = (data) => {
return data === '' || /^([0-9a-f]{2})+$/i.test(data);
};

const NO_ERRORS = 'No errors';

export async function getPubKey({ devicePath, accountIndex, showOnDevice }) {
let transport;
try {
Expand All @@ -20,7 +22,7 @@ export async function getPubKey({ devicePath, accountIndex, showOnDevice }) {
? await liskLedger.showAddressAndPubKey(ledgerAccount.derivePath())
: await liskLedger.getAddressAndPubKey(ledgerAccount.derivePath());
await transport?.close();
if (response?.error_message === 'No errors') {
if (response?.error_message === NO_ERRORS) {
return response?.pubKey;
}
return Promise.reject(response.return_code);
Expand All @@ -37,7 +39,7 @@ export async function getMultipleAddresses({ devicePath, accountIndexes }) {
const liskLedger = new LiskApp(transport);
const response = await liskLedger.getMultipleAddresses(accountIndexes);
await transport?.close();
if (response?.error_message === 'No errors') {
if (response?.error_message === NO_ERRORS) {
return response?.addr;
}
return Promise.reject(response.return_code);
Expand All @@ -58,7 +60,7 @@ export async function getSignedTransaction({ devicePath, accountIndex, unsignedM
Buffer.from(unsignedMessage, 'hex')
);
if (transport && transport.close) await transport.close();
if (response?.error_message === 'No errors') {
if (response?.error_message === NO_ERRORS) {
return response;
}
return Promise.reject(response.return_code);
Expand All @@ -80,7 +82,29 @@ export async function getSignedMessage({ devicePath, accountIndex, unsignedMessa
const response = await liskLedger.signMessage(ledgerAccount.derivePath(), message);
await transport?.close();

if (response?.error_message === 'No errors') {
if (response?.error_message === NO_ERRORS) {
return response;
}
return Promise.reject(response.return_code);
} catch (error) {
if (transport) await transport.close();
return Promise.reject(error);
}
}

export async function getSignedRawMessage({ devicePath, accountIndex, unsignedMessage }) {
let transport;
try {
transport = await TransportNodeHid.open(devicePath);
const liskLedger = new LiskApp(transport);
const ledgerAccount = getLedgerAccount(accountIndex);
const message = isHexString(unsignedMessage.substring(2))
? Buffer.from(unsignedMessage.substring(2), 'hex')
: Buffer.from(unsignedMessage);
const response = await liskLedger.claimMessage(ledgerAccount.derivePath(), message);
await transport?.close();

if (response?.error_message === NO_ERRORS) {
return response;
}
return Promise.reject(response.return_code);
Expand Down
11 changes: 6 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "Lisk",
"version": "3.0.1",
"version": "3.0.2-alpha.0",
"author": "Lisk Foundation <[email protected]>, lightcurve GmbH <[email protected]>",
"license": "GPL-3.0",
"productName": "Lisk",
Expand Down Expand Up @@ -114,13 +114,13 @@
},
"dependencies": {
"@hookform/resolvers": "2.8.8",
"@ledgerhq/hw-transport-node-hid": "6.27.17-next.0",
"@ledgerhq/hw-transport-node-hid": "6.28.5",
"@liskhq/lisk-client": "6.0.1",
"@tanstack/react-query": "4.0.10",
"@tanstack/react-query-devtools": "4.2.1",
"@walletconnect/sign-client": "2.9.0",
"@walletconnect/utils": "2.9.0",
"@zondax/ledger-lisk": "0.0.2",
"@zondax/ledger-lisk": "0.0.3",
"async-await-queue": "2.1.3",
"await-to-js": "2.1.1",
"axios": "1.6.0",
Expand All @@ -131,6 +131,7 @@
"crypto-browserify": "^3.12.0",
"dompurify": "2.4.6",
"electron-localshortcut": "3.2.1",
"electron-log": "5.1.2",
"electron-store": "8.1.0",
"express": "4.18.2",
"express-rate-limit": "6.7.0",
Expand Down Expand Up @@ -191,6 +192,7 @@
"@babel/preset-env": "7.22.5",
"@babel/preset-react": "7.22.5",
"@cucumber/cucumber": "9.2.0",
"@electron/rebuild": "3.6.0",
"@electron/universal": "1.4.1",
"@playwright/test": "1.32.1",
"@svgr/webpack": "8.0.1",
Expand All @@ -213,12 +215,11 @@
"cpx": "1.5.0",
"cross-env": "7.0.3",
"css-loader": "5.2.4",
"electron": "27.1.0",
"electron": "29.3.0",
"electron-builder": "24.6.4",
"electron-builder-notarize": "1.5.1",
"electron-devtools-installer": "3.2.0",
"electron-ipc-mock": "0.0.3",
"electron-rebuild": "3.2.9",
"electron-updater": "6.1.4",
"enzyme": "3.11.0",
"enzyme-adapter-react-16": "1.15.7",
Expand Down
24 changes: 23 additions & 1 deletion src/modules/message/store/action.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { to } from 'await-to-js';
import { cryptography } from '@liskhq/lisk-client';
import { signMessageUsingHW } from '@wallet/utils/signMessage';
import { signMessageUsingHW, signClaimMessageUsingHW } from '@wallet/utils/signMessage';
import {
signMessageWithPrivateKey,
signClaimMessageWithPrivateKey,
Expand Down Expand Up @@ -46,6 +46,28 @@ export const signMessage =
export const signClaimMessage =
({ nextStep, portalMessage, privateKey, currentAccount }) =>
async () => {
if (currentAccount?.hw) {
const [error, signature] = await to(
signClaimMessageUsingHW({
account: currentAccount,
message: portalMessage,
})
);

if (error) {
return nextStep({ error, portalMessage });
}

const portalSignature = {
data: {
pubKey: currentAccount.metadata.pubkey,
r: `0x${signature.substring(0, 64)}`,
s: `0x${signature.substring(64)}`,
},
};

return nextStep({ signature: portalSignature, portalMessage });
}
const signature = signClaimMessageWithPrivateKey({
message: portalMessage,
privateKey,
Expand Down
48 changes: 46 additions & 2 deletions src/modules/message/store/action.test.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { cryptography } from '@liskhq/lisk-client';
import { mockHWAccounts } from '@hardwareWallet/__fixtures__';
import { mockHWAccounts, mockHWCurrentDevice } from '@hardwareWallet/__fixtures__';
import * as signMessageUtil from '@wallet/utils/signMessage';
import * as signMessageWithPrivateKeyUtils from '../utils/signMessageWithPrivateKey';
import { signMessage, signClaimMessage } from './action';

jest.spyOn(cryptography.ed, 'signAndPrintMessage');
jest.spyOn(cryptography.ed, 'printSignedMessage');
jest.spyOn(signMessageUtil, 'signMessageUsingHW');
jest.spyOn(signMessageUtil, 'signClaimMessageUsingHW');
jest.spyOn(signMessageWithPrivateKeyUtils, 'signClaimMessageWithPrivateKey');

const privateKey =
Expand Down Expand Up @@ -78,11 +79,38 @@ describe('signClaimMessage', () => {
pubkey: '5bb1138c01b7762318f5e8a8799573077caadb1c7333a5c631773a2ade4bbdb5',
},
};
const mockHWCurrentAccount = {
hw: mockHWCurrentDevice,
metadata: {
pubkey: '5bb1138c01b7762318f5e8a8799573077caadb1c7333a5c631773a2ade4bbdb5',
},
};
const portalMessage =
'0xe4dbb94d0f19e47b0cff8206bebc1fcf8d892325ab851e1a5bdab954711d926e000000000000000000';
afterEach(() => jest.clearAllMocks());

it('should call next step with signature', async () => {
it('should call next step with signature for hardware wallet accounts', async () => {
const claimResult =
'15e546e6df7a17960c00c80cb42a3968ca004f2d8efd044cb2bb14e83ba173b02fc4c40ad47b0eca722f3022d5d82874fad25a7c0264d8a31e20f17741a4e602';
signMessageUtil.signClaimMessageUsingHW.mockResolvedValue(claimResult);

const signedClaim = {
data: {
pubKey: '5bb1138c01b7762318f5e8a8799573077caadb1c7333a5c631773a2ade4bbdb5',
r: '0x15e546e6df7a17960c00c80cb42a3968ca004f2d8efd044cb2bb14e83ba173b0',
s: '0x2fc4c40ad47b0eca722f3022d5d82874fad25a7c0264d8a31e20f17741a4e602',
},
};
await signClaimMessage({
nextStep,
portalMessage,
privateKey,
currentAccount: mockHWCurrentAccount,
})();
expect(nextStep).toHaveBeenCalledWith({ signature: signedClaim, portalMessage });
});

it('should call next step with signature for regular accounts', async () => {
const claimResult =
'15e546e6df7a17960c00c80cb42a3968ca004f2d8efd044cb2bb14e83ba173b02fc4c40ad47b0eca722f3022d5d82874fad25a7c0264d8a31e20f17741a4e602';
signMessageWithPrivateKeyUtils.signClaimMessageWithPrivateKey.mockReturnValue(claimResult);
Expand All @@ -102,4 +130,20 @@ describe('signClaimMessage', () => {
})();
expect(nextStep).toHaveBeenCalledWith({ signature: signedClaim, portalMessage });
});

it('should call nextStep with error for hardware wallet accounts', async () => {
const error = { name: 'An error' };
signMessageUtil.signClaimMessageUsingHW.mockRejectedValue(error);
await signClaimMessage({
nextStep,
privateKey,
portalMessage,
currentAccount: mockHWCurrentAccount,
})();

expect(nextStep).toHaveBeenCalledWith({
error,
portalMessage,
});
});
});
Loading

0 comments on commit 36fcb58

Please sign in to comment.