Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
PeterBenc committed Aug 3, 2020
1 parent 9c01f91 commit 8849ea2
Show file tree
Hide file tree
Showing 2 changed files with 200 additions and 3 deletions.
@@ -1,14 +1,14 @@
import {CRYPTO_PROVIDER_TYPES} from '../constants'
import ShelleyJsCryptoProvider from './shelley-js-crypto-provider'
// import CardanoTrezorCryptoProvider from './cardano-trezor-crypto-provider'
import ShelleyTrezorCryptoProvider from './shelley-trezor-crypto-provider'
import ShelleyLedgerCryptoProvider from './shelley-ledger-crypto-provider'
import NamedError from '../../helpers/NamedError'

const ShelleyCryptoProviderFactory = (() => {
const getCryptoProvider = (cryptoProviderType, options) => {
switch (cryptoProviderType) {
// case CRYPTO_PROVIDER_TYPES.TREZOR:
// return CardanoTrezorCryptoProvider(options)
case CRYPTO_PROVIDER_TYPES.TREZOR:
return ShelleyTrezorCryptoProvider(options)

case CRYPTO_PROVIDER_TYPES.LEDGER:
return ShelleyLedgerCryptoProvider(options)
Expand Down
197 changes: 197 additions & 0 deletions app/frontend/wallet/shelley/shelley-trezor-crypto-provider.ts
@@ -0,0 +1,197 @@
// eslint-disable-next-line import/no-unresolved
import CachedDeriveXpubFactory from '../helpers/CachedDeriveXpubFactory'
import {ADALITE_SUPPORT_EMAIL} from '../constants'
import derivationSchemes from '../helpers/derivation-schemes'
import NamedError from '../../helpers/NamedError'
import debugLog from '../../helpers/debugLog'

const CardanoTrezorCryptoProvider = ({network, config}) => {
const derivationScheme = derivationSchemes.v2

const TrezorConnect = config.ADALITE_TREZOR_CONNECT_URL
? (window as any).TrezorConnect
: require('trezor-connect').default

TrezorConnect.manifest({
email: ADALITE_SUPPORT_EMAIL,
appUrl: config.ADALITE_SERVER_URL,
})

const isHwWallet = () => true
const getHwWalletName = () => 'Trezor'

const deriveXpub = CachedDeriveXpubFactory(derivationScheme, async (absDerivationPath) => {
const response = await TrezorConnect.cardanoGetPublicKey({
path: absDerivationPath,
showOnTrezor: false,
})
throwIfNotSuccess(response)
return Buffer.from(response.payload.publicKey, 'hex')
})

function deriveHdNode(childIndex) {
throw NamedError(
'UnsupportedOperationError',
'This operation is not supported on TrezorCryptoProvider!'
)
}

function sign(message, absDerivationPath) {
throw NamedError('UnsupportedOperationError', 'Operation not supported')
}

async function displayAddressForPath(absDerivationPath) {
const response = await TrezorConnect.cardanoGetAddress({
path: absDerivationPath,
showOnTrezor: true,
})

throwIfNotSuccess(response)
}

type CardanoTxInputType = {
address_n: Array<number>
prev_hash: Buffer
prev_index: number
}

type CardanoAddressParametersType = {
address_type: number // 0 for base address etc.
address_n: Array<number> // BIP32
address_n_staking: Array<number>
staking_key_hash?: Buffer
certificate_pointer?: any // TODO: CardanoBlockchainPointerType
}

type CardanoTxOutputType = {
address: string
amount: number
address_parameters?: CardanoAddressParametersType
}

type CardanoTxCertificateType = {
type: number
path: Array<number>
pool: Buffer
}

function prepareInput(input, addressToAbsPathMapper): CardanoTxInputType {
const data = {
address_n: addressToAbsPathMapper(input.address),
prev_hash: Buffer.from(input.txHash, 'hex'),
prev_index: input.outputIndex,
}

return data
}

function prepareOutput(output, addressToAbsPathMapper): CardanoTxOutputType {
const data: CardanoTxOutputType = {
address: output.address,
amount: output.coins,
}
let addressParameters: CardanoAddressParametersType
if (output.isChange) {
addressParameters = {
address_type: 0, // TODO: 0 for base address
address_n: output.spendingPath,
address_n_staking: output.stakingPath,
}
data.address_parameters = addressParameters
}
return data
}

function prepareCertificate(cert, addressToAbsPathMapper): CardanoTxCertificateType {
return {
type: cert.type,
path: addressToAbsPathMapper(cert.accountAddress),
pool: Buffer.from(cert.poolHash, 'hex'),
}
}

async function signTx(unsignedTx, rawInputTxs, addressToAbsPathMapper) {
const inputs = []
for (const input of unsignedTx.inputs) {
inputs.push(await prepareInput(input, addressToAbsPathMapper))
}

const outputs = []
for (const output of unsignedTx.outputs) {
const data = await prepareOutput(output, addressToAbsPathMapper)
outputs.push(data)
}

const certificates = []
for (const cert of unsignedTx.certs) {
const data = await prepareCertificate(cert)
certificates.push(data)
}
const withdrawals = []
const metadata = null

// inputs: List[CardanoTxInputType] = None,
// outputs: List[CardanoTxOutputType] = None,
// protocol_magic: int = None,
// fee: int = None,
// ttl: int = None,
// network_id: int = None,
// certificates: List[CardanoTxCertificateType] = None,
// withdrawals: List[CardanoTxWithdrawalType] = None,
// metadata: bytes = None,

const response = await TrezorConnect.cardanoSignTransaction({
inputs,
outputs,
protocol_magic: network.protocolMagic,
fee: unsignedTx.fee,
ttl: unsignedTx.ttl,
network_id: network.networkId,
certificates,
withdrawals,
metadata,
})

if (response.error || !response.success) {
debugLog(response)
throw NamedError('TrezorSignTxError', response.payload.error)
}

return {
txHash: response.payload.hash,
txBody: response.payload.body,
}
}

function getWalletSecret() {
throw NamedError('UnsupportedOperationError', 'Unsupported operation!')
}

function getDerivationScheme() {
return derivationScheme
}

function throwIfNotSuccess(response) {
if (response.error || !response.success) {
debugLog(response)
throw NamedError(
'TrezorError',
'Trezor operation failed, please make sure ad blockers are switched off for this site'
)
}
}

return {
getWalletSecret,
getDerivationScheme,
signTx,
displayAddressForPath,
deriveXpub,
isHwWallet,
getHwWalletName,
_sign: sign,
_deriveHdNode: deriveHdNode,
}
}

export default CardanoTrezorCryptoProvider

0 comments on commit 8849ea2

Please sign in to comment.