Skip to content

Commit 8b2d4a6

Browse files
committed
Implemented hardware wallet claim message signing
1 parent e0e48d2 commit 8b2d4a6

File tree

6 files changed

+83
-2
lines changed

6 files changed

+83
-2
lines changed

app/src/ipc.js

+9
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const { contextBridge, ipcRenderer } = require('electron');
88
const REQUEST = 'REQUEST';
99
const RESPONSE = 'RESPONSE';
1010
const GET_SIGNED_MESSAGE = 'GET_SIGNED_MESSAGE';
11+
const GET_SIGNED_RAW_MESSAGE = 'GET_SIGNED_RAW_MESSAGE';
1112
const GET_SIGNED_TRANSACTION = 'GET_SIGNED_TRANSACTION';
1213
const GET_PUB_KEY = 'GET_PUB_KEY';
1314
const GET_MULTIPLE_ADDRESSES = 'GET_MULTIPLE_ADDRESSES';
@@ -61,6 +62,9 @@ contextBridge.exposeInMainWorld('ipc', {
6162
[`${GET_SIGNED_MESSAGE}.${REQUEST}`]: (title) => {
6263
ipcRenderer.send(`${GET_SIGNED_MESSAGE}.${REQUEST}`, title);
6364
},
65+
[`${GET_SIGNED_RAW_MESSAGE}.${REQUEST}`]: (title) => {
66+
ipcRenderer.send(`${GET_SIGNED_RAW_MESSAGE}.${REQUEST}`, title);
67+
},
6468
[`${GET_CONNECTED_DEVICES}.${RESPONSE}`]: (func) => {
6569
ipcRenderer.once(`${GET_CONNECTED_DEVICES}.${RESPONSE}`, (event, ...args) => {
6670
func(event, ...args);
@@ -91,6 +95,11 @@ contextBridge.exposeInMainWorld('ipc', {
9195
func(event, ...args);
9296
});
9397
},
98+
[`${GET_SIGNED_RAW_MESSAGE}.${RESPONSE}`]: (func) => {
99+
ipcRenderer.once(`${GET_SIGNED_RAW_MESSAGE}.${RESPONSE}`, (event, ...args) => {
100+
func(event, ...args);
101+
});
102+
},
94103
[LEDGER_HW_HID_EVENT]: (func) => {
95104
ipcRenderer.on(LEDGER_HW_HID_EVENT, (event, ...args) => {
96105
func(event, ...args);

libs/hardwareWallet/ledger/constants.js

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ export const REQUEST = 'REQUEST';
33
export const LEDGER_HW_HID_EVENT = 'LEDGER_HW_HID_EVENT';
44
export const LEDGER_HW_IPC_CHANNELS = {
55
GET_SIGNED_MESSAGE: 'GET_SIGNED_MESSAGE',
6+
GET_SIGNED_RAW_MESSAGE: 'GET_SIGNED_RAW_MESSAGE',
67
GET_SIGNED_TRANSACTION: 'GET_SIGNED_TRANSACTION',
78
GET_PUB_KEY: 'GET_PUB_KEY',
89
GET_MULTIPLE_ADDRESSES: 'GET_MULTIPLE_ADDRESSES',

libs/hardwareWallet/ledger/ledgerLiskAppIPCChannel/clientLedgerHWCommunication/index.js

+11
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const {
88
GET_PUB_KEY,
99
GET_MULTIPLE_ADDRESSES,
1010
GET_SIGNED_MESSAGE,
11+
GET_SIGNED_RAW_MESSAGE,
1112
} = LEDGER_HW_IPC_CHANNELS;
1213

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

38+
export const getSignedRawMessage = async (devicePath, accountIndex, unsignedMessage) => {
39+
const signedRawMessage = await executeIPCCommand(GET_SIGNED_RAW_MESSAGE, {
40+
devicePath,
41+
accountIndex,
42+
unsignedMessage,
43+
});
44+
45+
return signedRawMessage;
46+
};
47+
3748
export const getPubKey = async (devicePath, accountIndex, showOnDevice) => {
3849
const pubKey = await executeIPCCommand(GET_PUB_KEY, {
3950
devicePath,

libs/hardwareWallet/ledger/ledgerLiskAppIPCChannel/index.js

+7
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
const {
1616
GET_CONNECTED_DEVICES,
1717
GET_SIGNED_MESSAGE,
18+
GET_SIGNED_RAW_MESSAGE,
1819
GET_PUB_KEY,
1920
GET_MULTIPLE_ADDRESSES,
2021
GET_SIGNED_TRANSACTION,
@@ -36,6 +37,12 @@ export const ledgerLiskAppIPCChannel = () => {
3637
return result;
3738
});
3839

40+
createIpcMainChannel(GET_SIGNED_RAW_MESSAGE, async (data) => {
41+
const id = `${GET_SIGNED_RAW_MESSAGE}-${Date.now()}`;
42+
const result = await getSequentiallyQueuedData(myq, id, () => getSignedMessage(data));
43+
return result;
44+
});
45+
3946
createIpcMainChannel(GET_PUB_KEY, async (data) => {
4047
const id = `${GET_PUB_KEY}-${Date.now()}`;
4148
const result = await getSequentiallyQueuedData(myq, id, () => getPubKey(data));

src/modules/message/store/action.js

+23-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { to } from 'await-to-js';
22
import { cryptography } from '@liskhq/lisk-client';
3-
import { signMessageUsingHW } from '@wallet/utils/signMessage';
3+
import { signMessageUsingHW, signClaimMessageUsingHW } from '@wallet/utils/signMessage';
44
import {
55
signMessageWithPrivateKey,
66
signClaimMessageWithPrivateKey,
@@ -46,6 +46,28 @@ export const signMessage =
4646
export const signClaimMessage =
4747
({ nextStep, portalMessage, privateKey, currentAccount }) =>
4848
async () => {
49+
if (currentAccount?.hw) {
50+
const [error, signature] = await to(
51+
signClaimMessageUsingHW({
52+
account: currentAccount,
53+
message: getUnsignedNonProtocolMessage(portalMessage),
54+
})
55+
);
56+
57+
if (error) {
58+
return nextStep({ error, portalMessage });
59+
}
60+
61+
const portalSignature = {
62+
data: {
63+
pubKey: currentAccount.metadata.pubkey,
64+
r: `0x${signature.substring(0, 64)}`,
65+
s: `0x${signature.substring(64)}`,
66+
},
67+
};
68+
69+
return nextStep({ signature: portalSignature, portalMessage });
70+
}
4971
const signature = signClaimMessageWithPrivateKey({
5072
message: portalMessage,
5173
privateKey,

src/modules/wallet/utils/signMessage.js

+32-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import i18next from 'i18next';
2-
import { getSignedMessage } from '@libs/hardwareWallet/ledger/ledgerLiskAppIPCChannel/clientLedgerHWCommunication';
2+
import {
3+
getSignedMessage,
4+
getSignedRawMessage,
5+
} from '@libs/hardwareWallet/ledger/ledgerLiskAppIPCChannel/clientLedgerHWCommunication';
36
import { IPCLedgerError } from '@libs/hardwareWallet/ledger/ledgerLiskAppIPCChannel/clientLedgerHWCommunication/utils';
47
import { txStatusTypes } from '@transaction/configuration/txStatus';
58

@@ -30,3 +33,31 @@ export const signMessageUsingHW = async ({ account, message }) => {
3033
throw new IPCLedgerError(error);
3134
}
3235
};
36+
37+
export const signClaimMessageUsingHW = async ({ account, message }) => {
38+
try {
39+
const signedMessage = await getSignedRawMessage(
40+
account.hw.path,
41+
account.metadata.accountIndex,
42+
message
43+
);
44+
let signature = signedMessage?.signature;
45+
46+
if (!signature) {
47+
throw new IPCLedgerError({
48+
message: i18next.t('The message signature has been canceled on your {{model}}', {
49+
model: account.hw.product,
50+
}),
51+
hwTxStatusType: txStatusTypes.hwRejected,
52+
});
53+
}
54+
55+
if (signature instanceof Uint8Array) {
56+
signature = Buffer.from(signature);
57+
}
58+
59+
return signature.toString('hex');
60+
} catch (error) {
61+
throw new IPCLedgerError(error);
62+
}
63+
};

0 commit comments

Comments
 (0)