import { Message , SignedMessage , Signature , KeyInfo , DEFAULT_HD_PATH , TEST_DEFAULT_HD_PATH , MethodMultisig , Cid , ChainEpoch , MethodInit } from "../Types" ; import { BaseWalletProvider } from "./BaseWalletProvider" ; import { MultisigProviderInterface , WalletProviderInterface } from "../ProviderInterfaces" ; import { Keystore } from "../../utils/keystore" ; import { LightWalletSigner } from "../../signers/LightWalletSigner" ; import { LotusClient } from "../.." ; import { addressAsBytes } from "@zondax/filecoin-signing-tools" ; import cbor from "ipld-dag-cbor" ; import cid from "cids" ; import BigNumber from "bignumber.js" ; import { createApproveMessage , createCancelMessage , createProposeMessage } from "../../utils/msig" ; interface LighWalletOptions { encKeystore ? : string ; hdPathString ? : string ; seedPhrase ? : string ; password ? : string ; } export class LightWalletProvider extends BaseWalletProvider implements WalletProviderInterface , MultisigProviderInterface { public keystore ! : Keystore ; private hdPathString = DEFAULT_HD_PATH ; private signer ! : LightWalletSigner ; private pwdCallback : Function ; constructor ( client , pwdCallback , path = DEFAULT_HD_PATH ) { super ( client ) ; this . pwdCallback = pwdCallback ; if ( path === 'test' || ! path ) this . hdPathString = TEST_DEFAULT_HD_PATH ; } public async newAddress ( ) { await this . keystore . newAddress ( 1 , this . pwdCallback ( ) ) ; const addresses = await this . getAddresses ( ) ; return addresses [ addresses . length - 1 ] ; } public async deleteAddress ( address ) { await this . keystore . deleteAddress ( address , this . pwdCallback ( ) ) ; } public async hasAddress ( address ) { return this . keystore . hasAddress ( address ) ; } public async exportPrivateKey ( address ) { const pk = await this . keystore . getPrivateKey ( address , this . pwdCallback ( ) ) ; return { Type : '1' , PrivateKey : pk as any , } ; } public async getAddresses ( ) { return await this . keystore . getAddresses ( ) ; } public async getDefaultAddress ( ) { return await this . keystore . getDefaultAddress ( ) ; } public async setDefaultAddress ( address ) { this . keystore . setDefaultAddress ( address ) ; } public async sendMessage ( msg ) { const signedMessage = await this . signMessage ( msg ) ; if ( signedMessage ) { await this . sendSignedMessage ( signedMessage ) ; return signedMessage as SignedMessage ; } return undefined as any ; } public async signMessage ( msg ) { return await this . signer . sign ( msg , this . pwdCallback ( ) ) ; } public async sign ( data ) { return undefined as any ; } public async verify ( address , data , sign ) { return undefined as any ; } param requiredNumberOfSenders param approvingAddresses param unlockDuration param initialBalance param senderAddressOfCreateMsg public async msigCreate ( requiredNumberOfSenders , approvingAddresses , startEpoch , unlockDuration , initialBalance , senderAddressOfCreateMsg ) { const addresses = [ ] ; approvingAddresses . forEach ( address => { addresses . push ( addressAsBytes ( address ) ) ; } ) ; const constructorParams = [ addresses , requiredNumberOfSenders , unlockDuration , startEpoch ] ; const serializedConstructorParams = cbor . util . serialize ( constructorParams ) ; const MultisigActorCodeID = new cid ( 'bafkqadtgnfwc6mrpnv2wy5djonuwo' ) ; const execParams = [ MultisigActorCodeID , serializedConstructorParams , ] ; const serializedParams = cbor . util . serialize ( execParams ) ; const buff = Buffer . from ( serializedParams ) ; let messageWithoutGasParams = { From : senderAddressOfCreateMsg , To : "t01" , Value : new BigNumber ( initialBalance ) , Method : MethodInit . Exec , Params : buff . toString ( 'base64' ) } ; const message = await this . createMessage ( messageWithoutGasParams as any ) ; const signedMessage = await this . signMessage ( message ) ; const msgCid = await this . sendSignedMessage ( signedMessage ) ; return msgCid ; } param address param recipientAddres param value param senderAddressOfProposeMsg public async msigProposeTransfer ( address , recipientAddres , value , senderAddressOfProposeMsg ) { const params = [ ] ; const messageWithoutGasParams = await createProposeMessage ( address , senderAddressOfProposeMsg , recipientAddres , value , 0 , params ) ; const message = await this . createMessage ( messageWithoutGasParams ) ; const signedMessage = await this . signMessage ( message ) ; const msgCid = await this . sendSignedMessage ( signedMessage ) ; return msgCid ; } param address param proposedTransactionId param signerAddress public async msigApproveTransfer ( address , proposedTransactionId , signerAddress ) { return null as any ; } param address param proposedMessageId param proposerAddress param recipientAddres param value param senderAddressOfApproveMsg public async msigApproveTransferTxHash ( address , proposedMessageId , proposerAddress , recipientAddres , value , senderAddressOfApproveMsg ) { const proposerId = await this . client . state . lookupId ( proposerAddress ) ; const messageWithoutGasParams = await createApproveMessage ( address , senderAddressOfApproveMsg , proposedMessageId , proposerId , recipientAddres , 0 , value , [ ] ) ; const message = await this . createMessage ( messageWithoutGasParams as any ) ; const signedMessage = await this . signMessage ( message ) ; const msgCid = await this . sendSignedMessage ( signedMessage ) ; return msgCid ; } param address param proposedMessageId param proposerAddress param recipientAddres param value param senderAddressOfCancelMsg public async msigCancelTransfer ( address , senderAddressOfCancelMsg , proposedMessageId , recipientAddres , value ) { const proposerId = await this . client . state . lookupId ( senderAddressOfCancelMsg ) ; const messageWithoutGasParams = await createCancelMessage ( address , senderAddressOfCancelMsg , proposedMessageId , proposerId , recipientAddres , 0 , value , [ ] ) ; const message = await this . createMessage ( messageWithoutGasParams as any ) ; const signedMessage = await this . signMessage ( message ) ; const msgCid = await this . sendSignedMessage ( signedMessage ) ; return msgCid ; } param address param senderAddressOfProposeMsg param newSignerAddress param increaseNumberOfRequiredSigners public async msigProposeAddSigner ( address , senderAddressOfProposeMsg , newSignerAddress , increaseNumberOfRequiredSigners ) { const params = [ addressAsBytes ( newSignerAddress ) , increaseNumberOfRequiredSigners ] ; const messageWithoutGasParams = await createProposeMessage ( address , senderAddressOfProposeMsg , address , '0' , MethodMultisig . AddSigner , params ) ; const message = await this . createMessage ( messageWithoutGasParams ) ; const signedMessage = await this . signMessage ( message ) ; const msgCid = await this . sendSignedMessage ( signedMessage ) ; return msgCid ; } param address param senderAddressOfApproveMsg param proposedMessageId param proposerAddress param newSignerAddress param increaseNumberOfRequiredSigners public async msigApproveAddSigner ( address , senderAddressOfApproveMsg , proposedMessageId , proposerAddress , newSignerAddress , increaseNumberOfRequiredSigners ) { const values = [ addressAsBytes ( newSignerAddress ) , increaseNumberOfRequiredSigners ] ; const proposerId = await this . client . state . lookupId ( proposerAddress ) ; const messageWithoutGasParams = await createApproveMessage ( address , senderAddressOfApproveMsg , proposedMessageId , proposerId , address , MethodMultisig . AddSigner , '0' , values ) ; const message = await this . createMessage ( messageWithoutGasParams as any ) ; const signedMessage = await this . signMessage ( message ) ; const msgCid = await this . sendSignedMessage ( signedMessage ) ; return msgCid ; } param address param senderAddressOfCancelMsg param proposedMessageId param newSignerAddress param increaseNumberOfRequiredSigners public async msigCancelAddSigner ( address , senderAddressOfCancelMsg , proposedMessageId , newSignerAddress , increaseNumberOfRequiredSigners ) { const values = [ addressAsBytes ( newSignerAddress ) , increaseNumberOfRequiredSigners ] ; const proposerId = await this . client . state . lookupId ( senderAddressOfCancelMsg ) ; const messageWithoutGasParams = await createCancelMessage ( address , senderAddressOfCancelMsg , proposedMessageId , proposerId , address , MethodMultisig . AddSigner , '0' , values ) ; const message = await this . createMessage ( messageWithoutGasParams as any ) ; const signedMessage = await this . signMessage ( message ) ; const msgCid = await this . sendSignedMessage ( signedMessage ) ; return msgCid ; } param address param senderAddressOfProposeMsg param oldSignerAddress param newSignerAddress public async msigProposeSwapSigner ( address , senderAddressOfProposeMsg , oldSignerAddress , newSignerAddress ) { const params = [ addressAsBytes ( oldSignerAddress ) , addressAsBytes ( newSignerAddress ) ] ; const messageWithoutGasParams = await createProposeMessage ( address , senderAddressOfProposeMsg , address , '0' , MethodMultisig . SwapSigner , params ) ; const message = await this . createMessage ( messageWithoutGasParams ) ; const signedMessage = await this . signMessage ( message ) ; const msgCid = await this . sendSignedMessage ( signedMessage ) ; return msgCid ; } param address param senderAddressOfApproveMsg param proposedMessageId param proposerAddress param oldSignerAddress param newSignerAddress public async msigApproveSwapSigner ( address , senderAddressOfApproveMsg , proposedMessageId , proposerAddress , oldSignerAddress , newSignerAddress ) { const values = [ addressAsBytes ( oldSignerAddress ) , addressAsBytes ( newSignerAddress ) ] ; const proposerId = await this . client . state . lookupId ( proposerAddress ) ; const messageWithoutGasParams = await createApproveMessage ( address , senderAddressOfApproveMsg , proposedMessageId , proposerId , address , MethodMultisig . SwapSigner , '0' , values ) ; const message = await this . createMessage ( messageWithoutGasParams as any ) ; const signedMessage = await this . signMessage ( message ) ; const msgCid = await this . sendSignedMessage ( signedMessage ) ; return msgCid ; } param address param senderAddressOfCancelMsg param proposedMessageId param oldSignerAddress param newSignerAddress public async msigCancelSwapSigner ( address , senderAddressOfCancelMsg , proposedMessageId , oldSignerAddress , newSignerAddress ) { const values = [ addressAsBytes ( oldSignerAddress ) , addressAsBytes ( newSignerAddress ) ] ; const proposerId = await this . client . state . lookupId ( senderAddressOfCancelMsg ) ; const messageWithoutGasParams = await createCancelMessage ( address , senderAddressOfCancelMsg , proposedMessageId , proposerId , address , MethodMultisig . SwapSigner , '0' , values ) ; const message = await this . createMessage ( messageWithoutGasParams as any ) ; const signedMessage = await this . signMessage ( message ) ; const msgCid = await this . sendSignedMessage ( signedMessage ) ; return msgCid ; } param address param senderAddressOfProposeMsg param addressToRemove param decreaseNumberOfRequiredSigners public async msigProposeRemoveSigner ( address , senderAddressOfProposeMsg , addressToRemove , decreaseNumberOfRequiredSigners ) { const params = [ addressAsBytes ( addressToRemove ) , decreaseNumberOfRequiredSigners ] ; const messageWithoutGasParams = await createProposeMessage ( address , senderAddressOfProposeMsg , address , '0' , MethodMultisig . RemoveSigner , params ) ; const message = await this . createMessage ( messageWithoutGasParams ) ; const signedMessage = await this . signMessage ( message ) ; const msgCid = await this . sendSignedMessage ( signedMessage ) ; return msgCid ; } ; param address param senderAddressOfApproveMsg param proposedMessageId param proposerAddress param addressToRemove param decreaseNumberOfRequiredSigners public async msigApproveRemoveSigner ( address , senderAddressOfApproveMsg , proposedMessageId , proposerAddress , addressToRemove , decreaseNumberOfRequiredSigners ) { const values = [ addressAsBytes ( addressToRemove ) , decreaseNumberOfRequiredSigners ] ; const proposerId = await this . client . state . lookupId ( proposerAddress ) ; const messageWithoutGasParams = await createApproveMessage ( address , senderAddressOfApproveMsg , proposedMessageId , proposerId , address , MethodMultisig . RemoveSigner , '0' , values ) ; const message = await this . createMessage ( messageWithoutGasParams as any ) ; const signedMessage = await this . signMessage ( message ) ; const msgCid = await this . sendSignedMessage ( signedMessage ) ; return msgCid ; } ; param address param senderAddressOfApproveMsg param proposedMessageId param addressToRemove param decreaseNumberOfRequiredSigners public async msigCancelRemoveSigner ( address , senderAddressOfCancelMsg , proposedMessageId , addressToRemove , decreaseNumberOfRequiredSigners ) { const values = [ addressAsBytes ( addressToRemove ) , decreaseNumberOfRequiredSigners ] ; const proposerId = await this . client . state . lookupId ( senderAddressOfCancelMsg ) ; const messageWithoutGasParams = await createCancelMessage ( address , senderAddressOfCancelMsg , proposedMessageId , proposerId , address , MethodMultisig . RemoveSigner , '0' , values ) ; const message = await this . createMessage ( messageWithoutGasParams as any ) ; const signedMessage = await this . signMessage ( message ) ; const msgCid = await this . sendSignedMessage ( signedMessage ) ; return msgCid ; } ; public async createLightWallet ( password ) { this . keystore = new Keystore ( ) ; const mnemonic = this . keystore . generateRandomSeed ( ) ; await this . keystore . createVault ( { hdPathString : this . hdPathString , seedPhrase : mnemonic , password : password , } ) ; this . signer = new LightWalletSigner ( this . keystore ) ; return mnemonic ; } public async recoverLightWallet ( mnemonic , password ) { this . keystore = new Keystore ( ) ; await this . keystore . createVault ( { hdPathString : this . hdPathString , seedPhrase : mnemonic , password : password , } ) ; this . signer = new LightWalletSigner ( this . keystore ) ; } public loadLightWallet ( encryptedWallet ) { this . keystore = new Keystore ( ) ; this . keystore . deserialize ( encryptedWallet ) ; this . signer = new LightWalletSigner ( this . keystore ) ; } public prepareToSave ( ) { return this . keystore . serialize ( ) ; } public getSigner ( ) { return this . signer ; } }