import { CF_PATH } from "@counterfactual/local-ganache-server" ; import { Node as NodeTypes } from "@counterfactual/types" ; import { Wallet } from "ethers" ; import { JsonRpcProvider , Provider , TransactionRequest } from "ethers/providers" ; import { parseEther } from "ethers/utils" ; import { fromExtendedKey } from "ethers/utils/hdnode" ; import { v4 as generateUUID } from "uuid" ; import { EXTENDED_PRIVATE_KEY_PATH , Node } from "../../src" ; import { computeRandomExtendedPrvKey } from "../../src/engine/xkeys" ; import MemoryLockService from "../services/memory-lock-service" ; import { MemoryMessagingService } from "../services/memory-messaging-service" ; import { MemoryStoreServiceFactory } from "../services/memory-store-service" ; import { A_EXTENDED_PRIVATE_KEY , B_EXTENDED_PRIVATE_KEY } from "../test-constants.jest" ; export interface NodeContext { node : Node ; store : NodeTypes . IStoreService ; } export interface SetupContext { [ nodeName ] : NodeContext ; } export async function setup ( global , nodeCPresent = false , newExtendedPrvKey = false , messagingService = new MemoryMessagingService ( ) , storeServiceFactory = new MemoryStoreServiceFactory ( ) ) { const setupContext = { } ; const nodeConfig = { STORE_KEY_PREFIX : process . env . FIREBASE_STORE_PREFIX_KEY ! } ; const provider = new JsonRpcProvider ( global [ "ganacheURL" ] ) ; const extendedPrvKeyA = A_EXTENDED_PRIVATE_KEY ; let extendedPrvKeyB = B_EXTENDED_PRIVATE_KEY ; if ( newExtendedPrvKey ) { const newExtendedPrvKeys = await generateNewFundedExtendedPrvKeys ( global [ "fundedPrivateKey" ] , provider ) ; extendedPrvKeyB = newExtendedPrvKeys . B_EXTENDED_PRV_KEY ; } const lockService = new MemoryLockService ( ) ; const storeServiceA = storeServiceFactory . createStoreService ! ( `${ process . env . FIREBASE_STORE_SERVER_KEY ! }_${ generateUUID ( ) }` ) ; await storeServiceA . set ( [ { path : EXTENDED_PRIVATE_KEY_PATH , value : extendedPrvKeyA } ] ) ; const nodeA = await Node . create ( messagingService , storeServiceA , global [ "networkContext" ] , nodeConfig , provider , lockService ) ; setupContext [ "A" ] = { node : nodeA , store : storeServiceA } ; const storeServiceB = storeServiceFactory . createStoreService ! ( `${ process . env . FIREBASE_STORE_SERVER_KEY ! }_${ generateUUID ( ) }` ) ; await storeServiceB . set ( [ { path : EXTENDED_PRIVATE_KEY_PATH , value : extendedPrvKeyB } ] ) ; const nodeB = await Node . create ( messagingService , storeServiceB , global [ "networkContext" ] , nodeConfig , provider , lockService ) ; setupContext [ "B" ] = { node : nodeB , store : storeServiceB } ; let nodeC ; if ( nodeCPresent ) { const storeServiceC = storeServiceFactory . createStoreService ! ( `${ process . env . FIREBASE_STORE_SERVER_KEY ! }_${ generateUUID ( ) }` ) ; nodeC = await Node . create ( messagingService , storeServiceC , global [ "networkContext" ] , nodeConfig , provider , lockService ) ; setupContext [ "C" ] = { node : nodeC , store : storeServiceC } ; } return setupContext ; } export async function generateNewFundedWallet ( fundedPrivateKey , provider ) { const fundedWallet = new Wallet ( fundedPrivateKey , provider ) ; const wallet = Wallet . createRandom ( ) . connect ( provider ) ; const transactionToA = { to : wallet . address , value : parseEther ( "20" ) . toHexString ( ) } ; await fundedWallet . sendTransaction ( transactionToA ) ; return wallet ; } export async function generateNewFundedExtendedPrvKeys ( fundedPrivateKey , provider ) { const fundedWallet = new Wallet ( fundedPrivateKey , provider ) ; const A_EXTENDED_PRV_KEY = computeRandomExtendedPrvKey ( ) ; const B_EXTENDED_PRV_KEY = computeRandomExtendedPrvKey ( ) ; const signerAPrivateKey = fromExtendedKey ( A_EXTENDED_PRV_KEY ) . derivePath ( CF_PATH ) . privateKey ; const signerBPrivateKey = fromExtendedKey ( B_EXTENDED_PRV_KEY ) . derivePath ( CF_PATH ) . privateKey ; const signerAAddress = new Wallet ( signerAPrivateKey ) . address ; const signerBAddress = new Wallet ( signerBPrivateKey ) . address ; const transactionToA = { to : signerAAddress , value : parseEther ( "1" ) . toHexString ( ) } ; const transactionToB = { to : signerBAddress , value : parseEther ( "1" ) . toHexString ( ) } ; await fundedWallet . sendTransaction ( transactionToA ) ; await fundedWallet . sendTransaction ( transactionToB ) ; return { A_EXTENDED_PRV_KEY , B_EXTENDED_PRV_KEY } ; }