Skip to content

Commit 9c2eca7

Browse files
2.0.2: [feature] Adds personal_sign to hardware wallets (#951)
* 2.0.2: [feature] Adds personal_sign to hardware wallets * un-update versions
1 parent b2d0624 commit 9c2eca7

File tree

5 files changed

+108
-89
lines changed

5 files changed

+108
-89
lines changed

packages/common/src/types.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,12 @@ export type RequestPatch = {
4949
params: EthSignMessageRequest['params']
5050
}) => Promise<string>)
5151
| null
52+
personal_sign?:
53+
| ((args: {
54+
baseRequest: EIP1193Provider['request']
55+
params: PersonalSignMessageRequest['params']
56+
}) => Promise<string>)
57+
| null
5258
eth_signTypedData?:
5359
| ((args: {
5460
baseRequest: EIP1193Provider['request']
@@ -335,6 +341,12 @@ export interface EthSignMessageRequest {
335341
params: [Address, Message]
336342
}
337343

344+
//https://geth.ethereum.org/docs/rpc/ns-personal#personal_sign
345+
export interface PersonalSignMessageRequest {
346+
method: 'personal_sign'
347+
params: [Message, Address]
348+
}
349+
338350
// request -> signTypedData_v3`
339351
export interface EIP712Request {
340352
method: 'eth_signTypedData'
@@ -390,6 +402,7 @@ export interface EIP1193Provider extends SimpleEventEmitter {
390402
request(args: EthChainIdRequest): Promise<ChainId>
391403
request(args: EthSignTransactionRequest): Promise<string>
392404
request(args: EthSignMessageRequest): Promise<string>
405+
request(args: PersonalSignMessageRequest): Promise<string>
393406
request(args: EIP712Request): Promise<string>
394407
request(args: { method: string; params?: Array<unknown> }): Promise<unknown>
395408
disconnect?(): void

packages/keepkey/src/index.ts

Lines changed: 35 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,37 @@ function keepkey(): WalletInit {
240240
return accounts
241241
}
242242

243+
const signMessage = async (address: string, message: string) => {
244+
if (
245+
!accounts ||
246+
!Array.isArray(accounts) ||
247+
!(accounts.length && accounts.length > 0)
248+
)
249+
throw new Error(
250+
'No account selected. Must call eth_requestAccounts first.'
251+
)
252+
253+
const account =
254+
accounts.find(account => account.address === address) || accounts[0]
255+
256+
const { derivationPath } = account
257+
const accountIdx = getAccountIdx(derivationPath)
258+
const { addressNList } = getPaths(accountIdx)
259+
260+
const { signature } = await keepKeyWallet.ethSignMessage({
261+
addressNList,
262+
message:
263+
message.slice(0, 2) === '0x'
264+
? // @ts-ignore - commonjs weirdness
265+
(ethUtil.default || ethUtil)
266+
.toBuffer(message)
267+
.toString('utf8')
268+
: message
269+
})
270+
271+
return signature
272+
}
273+
243274
const request: EIP1193Provider['request'] = async ({
244275
method,
245276
params
@@ -383,37 +414,10 @@ function keepkey(): WalletInit {
383414

384415
return transactionHash as string
385416
},
386-
eth_sign: async ({ params: [address, message] }) => {
387-
if (
388-
!accounts ||
389-
!Array.isArray(accounts) ||
390-
!(accounts.length && accounts.length > 0)
391-
)
392-
throw new Error(
393-
'No account selected. Must call eth_requestAccounts first.'
394-
)
395-
396-
const account =
397-
accounts.find(account => account.address === address) ||
398-
accounts[0]
399-
400-
const { derivationPath } = account
401-
const accountIdx = getAccountIdx(derivationPath)
402-
const { addressNList } = getPaths(accountIdx)
403-
404-
const { signature } = await keepKeyWallet.ethSignMessage({
405-
addressNList,
406-
message:
407-
message.slice(0, 2) === '0x'
408-
? // @ts-ignore - commonjs weirdness
409-
(ethUtil.default || ethUtil)
410-
.toBuffer(message)
411-
.toString('utf8')
412-
: message
413-
})
414-
415-
return signature
416-
},
417+
eth_sign: async ({ params: [address, message] }) =>
418+
signMessage(address, message),
419+
personal_sign: async ({ params: [message, address] }) =>
420+
signMessage(address, message),
417421
eth_signTypedData: null,
418422
wallet_switchEthereumChain: async ({ params: [{ chainId }] }) => {
419423
currentChain =

packages/keystone/src/index.ts

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,18 @@ function keystone({
127127
return accounts
128128
}
129129

130+
const signMessage = (address: string, message: string) => {
131+
if (!(accounts && accounts.length && accounts.length > 0))
132+
throw new Error(
133+
'No account selected. Must call eth_requestAccounts first.'
134+
)
135+
136+
const account =
137+
accounts.find(account => account.address === address) || accounts[0]
138+
139+
return keyring.signMessage(account.address, message)
140+
}
141+
130142
const request = async ({
131143
method,
132144
params
@@ -168,12 +180,9 @@ function keystone({
168180
const accounts = await getAccounts()
169181
return accounts.map(({ address }) => address)
170182
},
171-
eth_accounts: async () => {
172-
return accounts && accounts[0].address ? [accounts[0].address] : []
173-
},
174-
eth_chainId: async () => {
175-
return currentChain.id
176-
},
183+
eth_accounts: async () =>
184+
accounts && accounts[0].address ? [accounts[0].address] : [],
185+
eth_chainId: async () => currentChain.id,
177186
eth_signTransaction: async ({ params: [transactionObject] }) => {
178187
if (!accounts)
179188
throw new Error(
@@ -236,18 +245,10 @@ function keystone({
236245

237246
return transactionHash as string
238247
},
239-
eth_sign: async ({ params: [address, message] }) => {
240-
if (!(accounts && accounts.length && accounts.length > 0))
241-
throw new Error(
242-
'No account selected. Must call eth_requestAccounts first.'
243-
)
244-
245-
const account =
246-
accounts.find(account => account.address === address) ||
247-
accounts[0]
248-
249-
return keyring.signMessage(account.address, message)
250-
},
248+
eth_sign: async ({ params: [address, message] }) =>
249+
signMessage(address, message),
250+
personal_sign: async ({ params: [message, address] }) =>
251+
signMessage(address, message),
251252
eth_signTypedData: async ({ params: [address, typedData] }) => {
252253
if (!(accounts && accounts.length && accounts.length > 0))
253254
throw new Error(

packages/ledger/src/index.ts

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,30 @@ function ledger({
195195
return accounts
196196
}
197197

198+
const signMessage = async (address: string, message: string) => {
199+
if (!(accounts && accounts.length && accounts.length > 0))
200+
throw new Error(
201+
'No account selected. Must call eth_requestAccounts first.'
202+
)
203+
204+
const account =
205+
accounts.find(account => account.address === address) || accounts[0]
206+
207+
return eth
208+
.signPersonalMessage(
209+
account.derivationPath,
210+
Buffer.from(message).toString('hex')
211+
)
212+
.then(result => {
213+
let v = (result['v'] - 27).toString(16)
214+
if (v.length < 2) {
215+
v = '0' + v
216+
}
217+
218+
return `0x${result['r']}${result['s']}${v}`
219+
})
220+
}
221+
198222
const request: EIP1193Provider['request'] = async ({
199223
method,
200224
params
@@ -332,30 +356,10 @@ function ledger({
332356

333357
return transactionHash as string
334358
},
335-
eth_sign: async ({ params: [address, message] }) => {
336-
if (!(accounts && accounts.length && accounts.length > 0))
337-
throw new Error(
338-
'No account selected. Must call eth_requestAccounts first.'
339-
)
340-
341-
const account =
342-
accounts.find(account => account.address === address) ||
343-
accounts[0]
344-
345-
return eth
346-
.signPersonalMessage(
347-
account.derivationPath,
348-
Buffer.from(message).toString('hex')
349-
)
350-
.then(result => {
351-
let v = (result['v'] - 27).toString(16)
352-
if (v.length < 2) {
353-
v = '0' + v
354-
}
355-
356-
return `0x${result['r']}${result['s']}${v}`
357-
})
358-
},
359+
eth_sign: async ({ params: [address, message] }) =>
360+
signMessage(address, message),
361+
personal_sign: async ({ params: [message, address] }) =>
362+
signMessage(address, message),
359363
eth_signTypedData: async ({ params: [address, typedData] }) => {
360364
if (!(accounts && accounts.length && accounts.length > 0))
361365
throw new Error(

packages/trezor/src/index.ts

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -468,19 +468,16 @@ function trezor(options: TrezorOptions): WalletInit {
468468
const accounts = await getAccountFromAccountSelect()
469469
return accounts.map(({ address }) => address)
470470
},
471-
eth_accounts: async () => {
472-
return Array.isArray(accounts) &&
473-
accounts.length &&
474-
accounts[0].hasOwnProperty('address')
471+
eth_accounts: async () =>
472+
Array.isArray(accounts) &&
473+
accounts.length &&
474+
accounts[0].hasOwnProperty('address')
475475
? [accounts[0].address]
476-
: []
477-
},
478-
eth_chainId: async () => {
479-
return currentChain.hasOwnProperty('id') ? currentChain.id : ''
480-
},
481-
eth_signTransaction: async ({ params: [transactionObject] }) => {
482-
return signTransaction(transactionObject)
483-
},
476+
: [],
477+
eth_chainId: async () =>
478+
currentChain.hasOwnProperty('id') ? currentChain.id : '',
479+
eth_signTransaction: async ({ params: [transactionObject] }) =>
480+
signTransaction(transactionObject),
484481
eth_sendTransaction: async ({ baseRequest, params }) => {
485482
const signedTx = await provider.request({
486483
method: 'eth_signTransaction',
@@ -494,10 +491,10 @@ function trezor(options: TrezorOptions): WalletInit {
494491

495492
return transactionHash as string
496493
},
497-
eth_sign: async ({ params: [address, message] }) => {
498-
let messageData = { data: message }
499-
return signMessage(address, messageData)
500-
},
494+
eth_sign: async ({ params: [address, message] }) =>
495+
signMessage(address, { data: message }),
496+
personal_sign: async ({ params: [message, address] }) =>
497+
signMessage(address, { data: message }),
501498
wallet_switchEthereumChain: async ({ params: [{ chainId }] }) => {
502499
currentChain =
503500
chains.find(({ id }) => id === chainId) || currentChain

0 commit comments

Comments
 (0)