import { bigNumberify , BigNumberish , computeAddress , parseEther } from "ethers/utils" ; import { fromExtendedKey , HDNode } from "ethers/utils/hdnode" ; import { BalanceRequest , Deposit , User , AssetType } from "../store/types" ; import { CounterfactualEvent , CounterfactualMethod } from "../types" ; import delay from "./delay" ; export function xkeyKthAddress ( xkey , k ) { return computeAddress ( xkeyKthHDNode ( xkey , k ) . publicKey ) ; } export function xkeyKthHDNode ( xkey , k ) { return fromExtendedKey ( xkey ) . derivePath ( `${ k }` ) ; } export async function getNodeAddress ( ) { const data = await window . ethereum . send ( CounterfactualMethod . GetNodeAddress ) ; return data . result ; } export async function getUserFromStoredToken ( ) { const data = await window . ethereum . send ( CounterfactualMethod . RequestUser ) ; return data . result ; } export async function storeTokenFromUser ( { token } ) { window . ethereum . send ( CounterfactualMethod . SetUser , [ token ] ) ; } export function buildRegistrationSignaturePayload ( data ) { return [ "PLAYGROUND ACCOUNT REGISTRATION" , `Username: ${ data . username }` , `E-mail: ${ data . email }` , `Ethereum address: ${ data . ethAddress }` , `Node address: ${ data . nodeAddress }` ] . join ( "\n" ) ; } export function buildSignatureMessageForLogin ( ethAddress ) { return [ "PLAYGROUND ACCOUNT LOGIN" , `Ethereum address: ${ ethAddress }` ] . join ( "\n" ) ; } export async function forMultisig ( ) { return new Promise ( async ( resolve ) => { const data = await window . ethereum . send ( CounterfactualEvent . CreateChannel ) ; return resolve ( data . result . data . multisigAddress ) ; } ) ; } export async function requestWithdraw ( { amount , multisigAddress , ethAddress , tokenAddress } ) { return window . ethereum . send ( CounterfactualMethod . RequestWithdraw , [ amount , multisigAddress , ethAddress , tokenAddress ] ) ; } export async function requestDeposit ( { amount , multisigAddress , tokenAddress } ) { return window . ethereum . send ( CounterfactualMethod . RequestDeposit , [ amount , multisigAddress , tokenAddress ] ) ; } export async function forFunds ( { multisigAddress , nodeAddress , tokenAddress } , fundsOwner ? ) { const MINIMUM_EXPECTED_BALANCE = parseEther ( "0.01" ) ; const freeBalance = ( await window . ethereum . send ( CounterfactualMethod . RequestBalances , [ multisigAddress , tokenAddress ] ) ) . result ; const freeBalanceAddress = xkeyKthAddress ( nodeAddress , 0 ) ; const counterpartyFreeBalanceAddress = Object . keys ( freeBalance ) . find ( address => address !== freeBalanceAddress ) as string ; const myBalance = bigNumberify ( freeBalance [ freeBalanceAddress ] ) ; const counterpartyBalance = bigNumberify ( freeBalance [ counterpartyFreeBalanceAddress ] ) ; const enoughCounterpartyBalance = counterpartyBalance . gte ( MINIMUM_EXPECTED_BALANCE ) ; const enoughMyBalance = myBalance . gte ( MINIMUM_EXPECTED_BALANCE ) ; switch ( fundsOwner ) { case "user" : if ( enoughMyBalance ) { return myBalance ; } break ; case "counterparty" : if ( enoughCounterpartyBalance ) { return myBalance ; } break ; case "both" : default : if ( enoughCounterpartyBalance && enoughMyBalance ) { return myBalance ; } break ; } await delay ( 1000 ) ; return forFunds ( { multisigAddress , nodeAddress , tokenAddress } , fundsOwner ) ; } export async function getCFBalances ( { multisigAddress , nodeAddress , tokenAddress } ) { const freeBalance = ( await window . ethereum . send ( CounterfactualMethod . RequestBalances , [ multisigAddress , tokenAddress ] ) ) . result ; const freeBalanceAddress = xkeyKthAddress ( nodeAddress , 0 ) ; return bigNumberify ( freeBalance [ freeBalanceAddress ] ) ; } export async function getIndexedCFBalances ( { multisigAddress , nodeAddress } ) { const indexedBalances = ( await window . ethereum . send ( CounterfactualMethod . RequestIndexedBalances , [ multisigAddress ] ) ) . result ; const freeBalanceAddress = xkeyKthAddress ( nodeAddress , 0 ) ; return Object . entries ( indexedBalances ) . map ( ( [ tokenAddress , balances ] ) => ( { tokenAddress , counterfactualBalance : balances [ freeBalanceAddress ] } ) ) ; } export async function getChannelAddresses ( ) { const { multisigAddresses } = ( await window . ethereum . send ( CounterfactualMethod . RequestChannels ) ) . result ; return multisigAddresses ; } export async function getChannel ( multisigAddress ) { const { data } = ( await window . ethereum . send ( CounterfactualMethod . RequestChannel , [ multisigAddress ] ) ) . result ; return data ; }