import Portis from "@portis/web3" ; import * as core from "@shapeshiftoss/hdwallet-core" ; import _ from "lodash" ; import Web3 from "web3" ; import * as btc from "./bitcoin" ; import * as eth from "./ethereum" ; class PortisTransport extends core . Transport { public async getDeviceID ( ) { return "portis:0" ; } public call ( ... args ) { return Promise . resolve ( ) ; } } export function isPortis ( wallet ) { return _ . isObject ( wallet ) && ( wallet as any ) . _isPortis ; } type HasNonTrivialConstructor < T > = T extends { new ( ) : any ; } ? never : T ; export type Portis = InstanceType < HasNonTrivialConstructor < typeof Portis > > ; export class PortisHDWallet implements core . HDWallet , core . ETHWallet , core . BTCWallet { readonly _supportsETH = true ; readonly _supportsETHInfo = true ; readonly _supportsBTCInfo = true ; readonly _supportsBTC = true ; readonly _isPortis = true ; transport : core . Transport = new PortisTransport ( new core . Keyring ( ) ) ; portis : Portis ; web3 : any ; info : PortisHDWalletInfo & core . HDWalletInfo ; ethAddress ? : string ; portisCallInProgress : Promise < any > = Promise . resolve ( ) ; constructor ( portis ) { this . portis = portis ; this . web3 = new Web3 ( portis . provider ) ; this . info = new PortisHDWalletInfo ( ) ; } async getFeatures ( ) { return { } ; } public async isLocked ( ) { return false ; } public getVendor ( ) { return "Portis" ; } public async getModel ( ) { return "portis" ; } public async getLabel ( ) { return "Portis" ; } public initialize ( ) { return Promise . resolve ( ) ; } public hasOnDevicePinEntry ( ) { return this . info . hasOnDevicePinEntry ( ) ; } public hasOnDevicePassphrase ( ) { return this . info . hasOnDevicePassphrase ( ) ; } public hasOnDeviceDisplay ( ) { return this . info . hasOnDeviceDisplay ( ) ; } public hasOnDeviceRecovery ( ) { return this . info . hasOnDeviceRecovery ( ) ; } public hasNativeShapeShift ( srcCoin , dstCoin ) { return this . info . hasNativeShapeShift ( srcCoin , dstCoin ) ; } public supportsOfflineSigning ( ) { return true ; } public supportsBroadcast ( ) { return false ; } public async clearSession ( ) { await this . portis . logout ( ) ; } public ping ( msg ) { return Promise . resolve ( { msg : msg . msg } ) ; } public sendPin ( pin ) { return Promise . resolve ( ) ; } public sendPassphrase ( passphrase ) { return Promise . resolve ( ) ; } public sendCharacter ( charater ) { return Promise . resolve ( ) ; } public sendWord ( word ) { return Promise . resolve ( ) ; } public cancel ( ) { return Promise . resolve ( ) ; } public wipe ( ) { return Promise . resolve ( ) ; } public reset ( msg ) { return Promise . resolve ( ) ; } public recover ( msg ) { return Promise . resolve ( ) ; } public loadDevice ( msg ) { return this . portis . importWallet ( msg . mnemonic ) ; } public describePath ( msg ) { return this . info . describePath ( msg ) ; } public async getPublicKeys ( msg ) { const publicKeys = [ ] ; this . portisCallInProgress = new Promise ( async ( resolve , reject ) => { try { await this . portisCallInProgress ; } catch ( e ) { console . error ( e ) ; } for ( let i = 0 ; i < msg . length ; i ++ ) { const { addressNList , coin } = msg [ i ] ; const bitcoinSlip44 = 0x80000000 + core . slip44ByCoin ( "Bitcoin" ) ; const portisResult = await this . portis . getExtendedPublicKey ( core . addressNListToBIP32 ( addressNList ) , addressNList [ 1 ] === bitcoinSlip44 ? "Bitcoin" : "" ) ; const { result , error } = portisResult ; if ( error ) reject ( error ) ; publicKeys . push ( { xpub : result } ) ; } resolve ( publicKeys ) ; } ) ; return this . portisCallInProgress ; } public async isInitialized ( ) { return true ; } public disconnect ( ) { return Promise . resolve ( ) ; } public async btcGetAddress ( msg ) { return btc . btcGetAddress ( msg , this . portis ) ; } public async btcSignTx ( msg ) { return btc . btcSignTx ( msg , this . portis ) ; } public async btcSignMessage ( msg ) { throw new Error ( "not supported" ) ; } public async btcVerifyMessage ( msg ) { return btc . btcVerifyMessage ( msg ) ; } public async btcSupportsCoin ( coin ) { return this . info . btcSupportsCoin ( coin ) ; } public async btcSupportsScriptType ( coin , scriptType ) { return this . info . btcSupportsScriptType ( coin , scriptType ) ; } public async btcSupportsSecureTransfer ( ) { return this . info . btcSupportsSecureTransfer ( ) ; } public btcSupportsNativeShapeShift ( ) { return this . info . btcSupportsNativeShapeShift ( ) ; } public btcGetAccountPaths ( msg ) { return this . info . btcGetAccountPaths ( msg ) ; } public btcIsSameAccount ( msg ) { return this . info . btcIsSameAccount ( msg ) ; } public btcNextAccountPath ( msg ) { return this . info . btcNextAccountPath ( msg ) ; } public async ethSupportsNetwork ( chainId = 1 ) { return this . info . ethSupportsNetwork ( chainId ) ; } public async ethSupportsSecureTransfer ( ) { return this . info . ethSupportsSecureTransfer ( ) ; } public ethSupportsNativeShapeShift ( ) { return this . info . ethSupportsNativeShapeShift ( ) ; } public async ethSupportsEIP1559 ( ) { return await this . info . ethSupportsEIP1559 ( ) ; } public async ethVerifyMessage ( msg ) { return eth . ethVerifyMessage ( msg , this . web3 ) ; } public ethNextAccountPath ( msg ) { return this . info . ethNextAccountPath ( msg ) ; } public async ethSignTx ( msg ) { return eth . ethSignTx ( msg , this . web3 , await this . _ethGetAddress ( ) ) ; } public async ethSignMessage ( msg ) { return eth . ethSignMessage ( msg , this . web3 , await this . _ethGetAddress ( ) ) ; } public ethGetAccountPaths ( msg ) { return this . info . ethGetAccountPaths ( msg ) ; } public async ethGetAddress ( msg ) { if ( msg . showDisplay === true ) { this . portis . showPortis ( ) ; } return this . _ethGetAddress ( ) ; } public async getDeviceID ( ) { return "portis:" + ( await this . _ethGetAddress ( ) ) ; } public async getFirmwareVersion ( ) { return "portis" ; } public async _ethGetAddress ( ) { if ( this . ethAddress ) return this . ethAddress ; const out = ( await this . web3 . eth . getAccounts ( ) ) [ 0 ] ; this . ethAddress = out ; return out ; } } export class PortisHDWalletInfo implements core . HDWalletInfo , core . ETHWalletInfo , core . BTCWalletInfo { readonly _supportsBTCInfo = true ; readonly _supportsETHInfo = true ; public getVendor ( ) { return "Portis" ; } public hasOnDevicePinEntry ( ) { return true ; } public hasOnDevicePassphrase ( ) { return true ; } public hasOnDeviceDisplay ( ) { return true ; } public hasOnDeviceRecovery ( ) { return true ; } public hasNativeShapeShift ( srcCoin , dstCoin ) { return false ; } public supportsOfflineSigning ( ) { return true ; } public supportsBroadcast ( ) { return false ; } public describePath ( msg ) { switch ( msg . coin ) { case "Ethereum" : return eth . describeETHPath ( msg . path ) ; case "Bitcoin" : return btc . describeUTXOPath ( msg . path , msg . coin , msg . scriptType ) ; default : throw new Error ( "Unsupported path" ) ; } } public async btcSupportsCoin ( coin ) { return btc . btcSupportsCoin ( coin ) ; } public async btcSupportsScriptType ( coin , scriptType ) { return btc . btcSupportsScriptType ( coin , scriptType ) ; } public async btcSupportsSecureTransfer ( ) { return Promise . resolve ( false ) ; } public btcSupportsNativeShapeShift ( ) { return false ; } public btcGetAccountPaths ( msg ) { return btc . btcGetAccountPaths ( msg ) ; } public btcIsSameAccount ( msg ) { return false ; } public btcNextAccountPath ( msg ) { return btc . btcNextAccountPath ( msg ) ; } public ethNextAccountPath ( msg ) { return undefined ; } public async ethSupportsNetwork ( chainId = 1 ) { return chainId === 1 ; } public async ethSupportsSecureTransfer ( ) { return false ; } public ethSupportsNativeShapeShift ( ) { return false ; } public async ethSupportsEIP1559 ( ) { return false ; } public ethGetAccountPaths ( msg ) { return eth . ethGetAccountPaths ( msg ) ; } } export function info ( ) { return new PortisHDWalletInfo ( ) ; } export function create ( portis ) { return new PortisHDWallet ( portis ) ; }