Skip to content

Commit

Permalink
Support signTypedData_v4 for Lattice (#596)
Browse files Browse the repository at this point in the history
  • Loading branch information
mholtzman committed Oct 11, 2021
1 parent 58025d0 commit 44be2c2
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 16 deletions.
11 changes: 4 additions & 7 deletions main/provider/index.js
Expand Up @@ -30,10 +30,6 @@ const { populate: populateTransaction, usesBaseFee, maxFee } = require('../trans

const version = require('../../package.json').version

function equalCaseInsensitive(s1, s2) {
return s1.toLowerCase() === s2.toLowerCase()
}

class Provider extends EventEmitter {
constructor () {
super()
Expand Down Expand Up @@ -206,7 +202,7 @@ class Provider extends EventEmitter {
const payload = req.payload
const [address, data] = payload.params

accounts.signTypedData(req.version, address, data, (err, sig) => {
accounts.signTypedData(req.version, address, { ...data }, (err, sig) => {
if (err) {
this.resError(err.message, payload, res)
cb(err.message)
Expand Down Expand Up @@ -481,9 +477,10 @@ class Provider extends EventEmitter {

if (
version !== 'V4' &&
equalCaseInsensitive((currentAccount.lastSignerType || ''), 'ledger')
['ledger', 'lattice'].includes((currentAccount.lastSignerType || '').toLowerCase())
) {
return this.resError('Ledger only supports eth_signTypedData_v4+', payload, res)
const signerName = currentAccount.lastSignerType[0].toUpperCase() + currentAccount.lastSignerType.substring(1)
return this.resError(`${signerName} only supports eth_signTypedData_v4+`, payload, res)
}

const handlerId = uuid()
Expand Down
22 changes: 16 additions & 6 deletions main/signers/lattice/Lattice/index.js
Expand Up @@ -159,7 +159,7 @@ class Lattice extends Signer {
try {
const req = {
currency: 'ETH',
startPath: [HARDENED_OFFSET + 44, HARDENED_OFFSET + 60, HARDENED_OFFSET, 0, 0],
startPath: this._getPath(0),
n: accountLimit,
skipCache: true
}
Expand Down Expand Up @@ -281,14 +281,18 @@ class Lattice extends Signer {
return Buffer.from(this.normalize(hex), 'hex')
}

_getPath (index) {
return [HARDENED_OFFSET + 44, HARDENED_OFFSET + 60, HARDENED_OFFSET, 0, index]
}

// Standard Methods
async _signMessage (index, protocol, payload) {
const clientSign = promisify(this.client.sign).bind(this.client)

const data = {
protocol: protocol,
payload: payload,
signerPath: [HARDENED_OFFSET + 44, HARDENED_OFFSET + 60, HARDENED_OFFSET, 0, index] // setup for other derivations
protocol,
payload,
signerPath: this._getPath(index)
}

const signOpts = {
Expand Down Expand Up @@ -322,7 +326,13 @@ class Lattice extends Signer {
}
}

async signTypedData (index, typedData, cb) {
async signTypedData (index, version, typedData, cb) {
const versionNum = (version.match(/[Vv](\d+)/) || [])[1]

if ((parseInt(versionNum) || 0) < 4) {
return cb(new Error(`Invalid version (${version}), Lattice only supports eth_signTypedData version 4+`), undefined)
}

try {
const signature = await this._signMessage(index, 'eip712', typedData)

Expand All @@ -344,7 +354,7 @@ class Lattice extends Signer {
nonce: utils.hexToNumber(txJson.nonce),
gasLimit: utils.hexToNumber(txJson.gasLimit),
useEIP155: true,
signerPath: [HARDENED_OFFSET + 44, HARDENED_OFFSET + 60, HARDENED_OFFSET, 0, index]
signerPath: this._getPath(index)
}

if (type) {
Expand Down
23 changes: 20 additions & 3 deletions test/main/provider/index.test.js
Expand Up @@ -3,8 +3,6 @@ import { utils } from 'ethers'
import { addHexPrefix } from 'ethereumjs-util'
import log from 'electron-log'

log.transports.console.level = false

const mockAccounts = {}
const mockStore = {
'main.accounts': {
Expand Down Expand Up @@ -45,13 +43,19 @@ jest.mock('../../../main/store', () => {
})

beforeAll(async () => {
log.transports.console.level = false

mockConnection = new MockConnection()

// need to import this after mocks are set up
provider = (await import('../../../main/provider')).default
provider.handlers = {}
})

afterAll(() => {
log.transports.console.level = 'debug'
})

describe('#getRawTx', () => {
it('leaves a valid value unchanged', () => {
const tx = provider.getRawTx({ value: '0x2540be400' })
Expand Down Expand Up @@ -408,7 +412,20 @@ describe('#send', () => {
const params = [address, typedData]

send({ method: 'eth_signTypedData_v3', params }, err => {
expect(err.error.message).toBeTruthy()
expect(err.error.message).toMatch(/Ledger/)
expect(err.error.code).toBe(-1)
done()
})
}, 100)

it('does not submit a V3 request to a Lattice', done => {
mockAccounts.current = () => ({ id: address, getAccounts: () => [address], lastSignerType: 'lattice' })

// Lattice only supports V4+
const params = [address, typedData]

send({ method: 'eth_signTypedData_v3', params }, err => {
expect(err.error.message).toMatch(/Lattice/)
expect(err.error.code).toBe(-1)
done()
})
Expand Down

0 comments on commit 44be2c2

Please sign in to comment.