UNPKG

spacylabs-rhino

Version:
99 lines (90 loc) 3.46 kB
const Eth = require('@ledgerhq/hw-app-eth').default const DVFError = require('../../dvf/DVFError') const BN = require('bignumber.js') const _findKey = require('lodash/findKey') const selectTransport = require('../../ledger/selectTransport') const provideContractData = require('../../ledger/provideContractData') const getTokenAddressFromTokenInfoOrThrow = require('../../dvf/token/getTokenAddressFromTokenInfoOrThrow') const swJS = require('@rhino.fi/starkware-crypto') const { starkLimitOrderToMessageHash } = require('@rhino.fi/dvf-utils') const getPublicKey = async (eth, starkPath) => { const tempKey = (await eth.starkGetPublicKey(starkPath)).toString('hex') return { x: tempKey.substr(2, 64), y: tempKey.substr(66) } } // Use signing on the starkMessage only as a fallback module.exports = async (dvf, path, starkOrder, { returnStarkPublicKey = true, starkMessage = null } = {}) => { const Transport = selectTransport(dvf.isBrowser) const buySymbol = _findKey(dvf.config.tokenRegistry, { starkTokenId: starkOrder.tokenBuy }) const sellSymbol = _findKey(dvf.config.tokenRegistry, { starkTokenId: starkOrder.tokenSell }) const buyTokenInfo = dvf.token.getTokenInfoOrThrow(buySymbol) const sellTokenInfo = dvf.token.getTokenInfoOrThrow(sellSymbol) const buyQuantization = new BN(buyTokenInfo.quantization) const sellQuantization = new BN(sellTokenInfo.quantization) const transport = await Transport.create() const eth = new Eth(transport) let address, starkPublicKey, starkPath try { ({ address } = await eth.getAddress(path)) starkPath = dvf.stark.ledger.getPath(address) starkPublicKey = returnStarkPublicKey ? await getPublicKey(eth, starkPath) : null } catch (error) { await transport.close() throw error } let buyTokenAddress = null let sellTokenAddress = null try { buyTokenAddress = getTokenAddressFromTokenInfoOrThrow(buyTokenInfo, 'ETHEREUM') sellTokenAddress = getTokenAddressFromTokenInfoOrThrow(sellTokenInfo, 'ETHEREUM') const buySignature = await provideContractData(dvf, eth, buyTokenAddress, buyQuantization, true) const sellSignature = await provideContractData(dvf, eth, sellTokenAddress, sellQuantization, true) if ((buySignature && buySignature.unsafeSign) || (sellSignature && sellSignature.unsafeSign)) { const message = starkMessage || starkLimitOrderToMessageHash(swJS)(starkOrder) const paddedMessage = `0x${message.padEnd(64, '0').substr(-64)}` const starkSignature = await eth.starkUnsafeSign( starkPath, paddedMessage ) await transport.close() return { starkSignature, starkPublicKey } } } catch (error) { await transport.close() throw new DVFError('LEDGER_TOKENINFO_ERR') } try { const starkSignature = await eth.starkSignOrder_v2( starkPath, sellTokenAddress, sellSymbol === 'ETH' ? 'eth' : 'erc20', new BN(sellTokenInfo.quantization), null, buyTokenAddress, buySymbol === 'ETH' ? 'eth' : 'erc20', new BN(buyTokenInfo.quantization), null, starkOrder.vaultIdSell, starkOrder.vaultIdBuy, new BN(starkOrder.amountSell), new BN(starkOrder.amountBuy), starkOrder.nonce, starkOrder.expirationTimestamp ) await transport.close() return { starkPublicKey, starkSignature } } catch (error) { await transport.close() throw error } }